c++ - 使用 SSE 进行比较和提取

标签 c++ c sse simd

使用 SSE 指令对两个整数寄存器进行成对比较和提取相等元素的最佳方法是什么?例如,如果 a = [6 4 7 2]b = [2 4 9 2](每个寄存器包含四个 32 位整数),结果应该是[4 2 x x]。这个问题的另一种形式是如何获得相等元素的二进制掩码 (..0101b),它可以用于洗牌或作为索引在预先计算的表中查找洗牌指令的参数。

最佳答案

不可能用一条指令提取和移动相等的元素。但是使用 pcmpeqd 可以很容易地实现相同元素的掩码:

__m128i zero = _mm_set1_epi32(0);
__m128i a = _mm_set_epi32(6, 4, 7, 2);
__m128i b = _mm_set_epi32(2, 4, 9, 2);

__m128i mask = _mm_cmp_epi32(a, b);     // mask is now 0, -1, 0, -1
mask = _mm_sub_epi32(zero, mask);       // mask is now 0,  1, 0,  1

编辑: 如果你想要一些带有混洗常量的查找表的索引,你需要额外的操作。喜欢

static const __m128i zero = _mm_set1_epi32(0);
static const __m128i bits = _mm_set_epi32(1,2,4,8);

__m128i a = _mm_set_epi32(6, 4, 7, 2);
__m128i b = _mm_set_epi32(2, 4, 9, 2);

__m128i bitvector = _mm_and_si128(bits, _mm_cmp_epi32(a, b));
bitvector = _mm_hadd_epi32(bitvector, bitvector);
bitvector = _mm_hadd_epi32(bitvector, bitvector);
// now a index from 0...15 is the the low 32 bit of bitvector

可能有比使用查找表计算洗牌更好的算法,可能使用 De Bruijn 乘法直接计算洗牌。 OTOH 如果您要比较的整数超过 4 个,额外的 4 个整数只会以 一个 额外的 phaddd 为代价。

关于c++ - 使用 SSE 进行比较和提取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10564309/

相关文章:

c - 为什么我的代码重复打印出“root is 51”这一行?

java - 面试问题 - 在排序数组 X 中搜索索引 i 使得 X[i] = i

c++ - C++ 模板中的类型优先级和整数类型

python - 为什么 protobuf 不适合大型数据结构?

c++ - __mm128 的 vector 不会 push_back()

performance - 为什么 SSE 标量 sqrt(x) 比 rsqrt(x) * x 慢?

c++ - SSE/SSE2 指令的打包和解包数据?

c++ - 使用 Cairo 和 Allegro 5

c - 检测 Windows shell 更改

c - 3 维数组表示