使用SIMD提取位

jia*_*ang 5 x86 bit-manipulation simd intrinsics avx2

我想从寄存器变量中提取8位,__mm256i src其中8位由另一个指定,__mm256i offset由8个整数组成.例如:如果offset[1,3,5,21,100,200,201,202],我想从第1,第3,第5,第100,第200,第201,第202位获取src并将它们打包到a int8.

这个问题类似于使用位操作提取位,但我想要一个带有SIMD指令的解决方案,因为它要快得多.

Erm*_*mIg 4

  1. 选择每个元素中的高 3 位,并使用内在_mm256_permutevar8x32_epi32 () 选择所需的 32 位元素。
  2. 选择向量每个元素中的低 5 位,并使用内在_mm256_sllv_epi32 () 创建位掩码。
  3. 使用_mm256_movemask_ps () 将结果打包为 int8(将 __m256i 转换为 __m256)。

下面有一个例子:

uint8_t Select(__m256i offset, __m256i src)
{
    __m256i permutedSrc = _mm256_permutevar8x32_epi32(src, _mm256_srli_epi32(offset, 5));
    __m256i shift = _mm256_and_si256(offset, _mm256_set1_epi32(31));
    __m256i bitmask = _mm256_sllv_epi32(_mm256_set1_epi32(1), shift);
    __m256i mask = _mm256_cmpeq_epi32(_mm256_and_si256(permutedSrc, bitmask), _mm256_setzero_si256());
    return ~_mm256_movemask_ps(_mm256_castsi256_ps(mask));
}
Run Code Online (Sandbox Code Playgroud)