如何在AVX2中从32位转换为16位未签名的整数

How to convert from 32-bit to 16-bit unsigned integers in AVX2?

本文关键字:16位 整数 转换 AVX2 中从 32位      更新时间:2023-10-16

i使用 _mm256_cvtps_epi32()从8 float s转换为8x32位整数。但是目标是到达16位未签名的整数。我有2个矢量a0a1,每种 __m256i类型。什么是包装它们的最快方法,以使a0的16位等效物进入结果的下部128位,而a1的等效物进入更高的128位?

这是我到目前为止所拥有的,其中p0p1是两个__m256向量,每个float s:

const __m256i vShuffle = _mm256_setr_epi8(
  0, 1, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 4, 5, 8, 9, 12, 13);
const __m256i a0 = _mm256_cvtps_epi32(p0);
const __m256i a1 = _mm256_cvtps_epi32(p1);
const __m256i b0 = _mm256_shuffle_epi8(a0, vShuffle);
const __m256i b1 = _mm256_shuffle_epi8(a1, vShuffle);
const __m128i c0 = _mm_or_si128(_mm256_extracti128_si256(b0, 0), _mm256_extracti128_si256(b0, 1));
const __m128i c1 = _mm_or_si128(_mm256_extracti128_si256(b1, 0), _mm256_extracti128_si256(b1, 1));
return _mm256_setr_m128i(c0, c1);

我没有测试该代码,但它应该为您提供技巧:

__m256i tmp1 = _mm256_cvtps_epi32(p0);
__m256i tmp2 = _mm256_cvtps_epi32(p1);
tmp1 = _mm256_packus_epi32(tmp1, tmp2);
tmp1 = _mm256_permute4x64_epi64(tmp1, 0xD8);
// _mm256_store_si256 this