基本上我如何用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
的内在函数,但我不确定这是否会起作用,因为我找不到它的用法示例。
答案 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