x86 - 使用 SIMD 提取位

标签 x86 bit-manipulation simd intrinsics avx2

我想从寄存器变量中提取 8 位 __mm256i src 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 指令的解决方案,因为它要快得多。

最佳答案

  • 在每个元素中选择高 3 位并使用内部 _mm256_permutevar8x32_epi32() 选择所需的 32 位元素。
  • 在向量的每个元素中选择低 5 位并使用内部 _mm256_sllv_epi32 () 创建位掩码。
  • 使用 _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));
    }
    

    关于x86 - 使用 SIMD 提取位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46824559/

    相关文章:

    x86 - SSE/AVX 是否提供确定结果是否四舍五入的方法?

    swift - 在 '*' 上引用运算符函数 'SIMD' 要求 '_.Scalar' 符合 'FloatingPoint'

    opencl - OpenCL SubSlice 是否类似于 CUDA Warp (SIMD)?

    assembly - ESP寄存器和SS寄存器有什么区别?

    string - Nasm equ $-获得错误的长度

    assembly - 为什么我在尝试处理 286 上的异常时会遇到三重错误,但在现代 CPU 或 Bochs 上却不会?

    c++ - 确定数的幂

    c - 如何在 C 中使用 #define 语句对类型为 `float` 的变量执行字节交换?

    java - 检查整数是另一个整数的位旋转

    java - 从 Java 确定是 x86 还是 x64 系统