如何在 AVX2 中将 32 位无符号整数转换为 16 位无符号整数?
How to convert from 32-bit to 16-bit unsigned integers in AVX2?
我使用 _mm256_cvtps_epi32()
将 8 float
转换为 8x32 位整数。但目标是获得 16 位无符号整数。我有 2 个向量 a0
和 a1
,每个都是 __m256i
类型。什么是最快的打包方式,使 a0
的 16 位等价物进入结果的低 128 位,而 a1
的等价物进入高 128 位?
这是我到目前为止得到的,其中 p0
和 p1
是两个 __m256
向量,每个向量有 8 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
我使用 _mm256_cvtps_epi32()
将 8 float
转换为 8x32 位整数。但目标是获得 16 位无符号整数。我有 2 个向量 a0
和 a1
,每个都是 __m256i
类型。什么是最快的打包方式,使 a0
的 16 位等价物进入结果的低 128 位,而 a1
的等价物进入高 128 位?
这是我到目前为止得到的,其中 p0
和 p1
是两个 __m256
向量,每个向量有 8 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