Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用SSE进行比较和提取_C++_C_Sse_Simd - Fatal编程技术网

C++ 使用SSE进行比较和提取

C++ 使用SSE进行比较和提取,c++,c,sse,simd,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 = _m

使用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多重应用程序直接计算洗牌。如果要比较的整数超过4个,那么额外的4个整数只需额外增加一个
phaddd

我可能会使用
drhirsch
建议的变体:

int index = _mm_movemask_ps((__m128)_mm_cmp_epi32(a, b));

这为您提供了只使用两个操作查找洗牌掩码时使用的相同索引。

减法会将相等的数字对转换为0。我实际上指的是一个位掩码,可以直接用于洗牌指令中,或者作为一个小索引来查找预计算表中的掩码,即在本例中,
掩码=…0101b=5d