如何使用 avx 指令将浮点数向量转换为短整型?



基本上我如何使用AVX2内部函数编写等效的东西?我们在这里假设result_in_float__m256型,而resultshort 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的内在函数,但我不确定这是否可以解决问题,因为我找不到它的用法示例。

_mm256_cvtps_epi32

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

由于可以假设这些值在正确的范围内(根据注释),因此我们可以使用_mm256_packs_epi32而不是_mm256_shuffle_epi8来进行转换,无论哪种方式,它都是端口 5 上的 1 周期指令,但使用_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

最新更新