【问题标题】:Extract bits with SIMD使用 SIMD 提取位
【发布时间】:2018-03-31 04:14:19
【问题描述】:

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

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

【问题讨论】:

    标签: x86 bit-manipulation simd intrinsics avx2


    【解决方案1】:
    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));
    }
    

    【讨论】:

    • 我想知道VPSHUFBITQMB 是否会在这里提供帮助。虽然我们要等到 Ice Lake 才能看到该说明。
    猜你喜欢
    • 2015-04-14
    • 2016-12-27
    • 2019-01-22
    • 2011-11-18
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多