使用SIMD提取位

时间:2017-10-19 07:20:35

标签: x86 bit-manipulation simd intrinsics avx2

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

这个问题类似于Extracting bits using bit manipulation,但我想要一个带有SIMD指令的解决方案,因为它要快得多。

1 个答案:

答案 0 :(得分:4)

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

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