如何在 AVX2 中将 32 位无符号整数转换为 16 位无符号整数?

Posted

技术标签:

【中文标题】如何在 AVX2 中将 32 位无符号整数转换为 16 位无符号整数?【英文标题】:How to convert from 32-bit to 16-bit unsigned integers in AVX2? 【发布时间】:2019-03-07 09:46:34 【问题描述】:

我使用 _mm256_cvtps_epi32() 将 8 个 floats 转换为 8x32 位整数。但目标是获得 16 位无符号整数。我有 2 个向量 a0a1,每个 __m256i 类型。打包它们以使 a0 的 16 位等价物进入结果的低 128 位,a1 的等价物进入高 128 位的最快方法是什么?

这是我目前得到的,其中p0p1 是两个__m256 向量,每个向量有8 个floats:

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);

【问题讨论】:

大概其中一个随机播放指令会起作用? @AlanBirtles,我试过_mm256_shuffle_epi8,但它不会在 128 位通道之间随机播放。 【参考方案1】:

我没有测试该代码,但它应该可以为您解决问题:

__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

【讨论】:

关于如何解决逆问题的任何提示?给定 __m256i 将其解压缩为 2 个 __m256 浮点向量。

以上是关于如何在 AVX2 中将 32 位无符号整数转换为 16 位无符号整数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?

如何从 32 位 R 整数中提取 4 位无符号整数?

使用 32 位无符号整数乘以 64 位数字的算法

如何在 C 中提取 32 位无符号整数的特定“n”位?

怎样将一个ip地址写成一个32位无符号整数形式

如何使用 sprintf 显示 64 位无符号整数?