如何使用avx指令将float向量转换为short int?

时间:2016-12-19 17:42:54

标签: c++ c gcc avx avx2

基本上我如何用AVX2内在函数编写相当于此的东西?我们在此假设result_in_float的类型为__m256,而result的类型为short int*short int[8]

for(i = 0; i < 8; i++)
    result[i] = (short int)result_in_float[i];

我知道使用__m256i _mm256_cvtps_epi32(__m256 m1)内在函数可以将浮点数转换为32位整数,但不知道如何将这些32位整数进一步转换为16位整数。而且我不仅仅想要这样,而且还要将这些值(以16位整数的形式)存储到内存中,我想使用向量指令来完成所有这些操作。

在互联网上搜索,我发现了一个名为_mm256_mask_storeu_epi16的内在函数,但我不确定这是否会起作用,因为我找不到它的用法示例。

1 个答案:

答案 0 :(得分:4)

_mm256_cvtps_epi32是一个很好的第一步,转换为短路的打包向量有点烦人,需要交叉切片混洗(所以它在这里不在依赖链中是好的。)

由于可以假设值在正确的范围内(根据注释),我们可以使用_mm256_packs_epi32而不是_mm256_shuffle_epi8来进行转换,无论哪种方式都是1周期指令在端口5上但是使用_mm256_packs_epi32避免了从某个地方获得一个随机掩码。

所以把它放在一起(未经测试)

__m256i tmp = _mm256_cvtps_epi32(result_in_float);
tmp = _mm256_packs_epi32(tmp, _mm256_setzero_si256());
tmp = _mm256_permute4x64_epi64(tmp, 0xD8);
__m128i res = _mm256_castsi256_si128(tmp);
// _mm_store_si128 that

最后一步(演员表)是免费的,它只是改变了类型。

如果您有两个浮动向量要转换,您可以重复使用大多数指令,例如:(未测试)

__m256i tmp1 = _mm256_cvtps_epi32(result_in_float1);
__m256i tmp2 = _mm256_cvtps_epi32(result_in_float2);
tmp1 = _mm256_packs_epi32(tmp1, tmp2);
tmp1 = _mm256_permute4x64_epi64(tmp1, 0xD8);
// _mm256_store_si256 this