我想从另一个由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));
}