Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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/7/wcf/4.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++ 确定SIMD比较寄存器位置的最快方法_C++_X86_Sse_Simd_Avx - Fatal编程技术网

C++ 确定SIMD比较寄存器位置的最快方法

C++ 确定SIMD比较寄存器位置的最快方法,c++,x86,sse,simd,avx,C++,X86,Sse,Simd,Avx,我有一个已比较的SIMD\uuu m128i寄存器,其结果如下: 0, 0, -1, -1, 0, 0, 0, 0 // in shorts 0, -1, 0, 0 // in ints 获取设置位的整数位置的最快/最便宜的方法是什么?\uuu m128i中只有一个int设置为1 例如: -1, -1, 0, 0, 0, 0, 0, 0 -> 0 0, 0, -1, -1, 0, 0, 0, 0 -> 1 0, 0, 0, 0, -1, -1, 0, 0 -> 2

我有一个已比较的SIMD
\uuu m128i
寄存器,其结果如下:

0, 0, -1, -1, 0, 0, 0, 0 // in shorts
0, -1, 0, 0 // in ints
获取设置位的整数位置的最快/最便宜的方法是什么?
\uuu m128i
中只有一个int设置为1

例如:

-1, -1, 0, 0, 0, 0, 0, 0  ->  0
0, 0, -1, -1, 0, 0, 0, 0  ->  1
0, 0, 0, 0, -1, -1, 0, 0  ->  2
0, 0, 0, 0, 0, 0, -1, -1  ->  3
另一个注意事项是,我只有AVX和更低版本可用,因此没有AVX2或AVX-512。我用C++和英特尔ISTIN。
编辑:这是我的当前代码:

__m128i comparableLow = _mm_set_epi32(key - 1, key - 1, key - 1, key - 1);
__m128i comparableHigh = _mm_set_epi32(key + 1, key + 1, key + 1, key + 1);

__m128i mData = _mm_loadu_si128((__m128i*)(arr));
__m128i l1 = _mm_cmpgt_epi32(mData, comparableLow);
__m128i u1 = _mm_cmplt_epi32(mData, comparableHigh);
__m128i r1 = _mm_and_si128(u1, l1);

vmovmskps
/
bsf
(或
tzcnt
)。看见如果这是
vpcmpeqd
vcmpps
的结果,则有dword元素,因此可以使用
movmskps
获取高位位图。或者如果您总是有成对的
int16\t
?IDK如果它们总是以32位块的形式出现,为什么要将其显示为
int16\t
元素。可能是重复的(除了字节元素,所以可能不是)。然后对这些指令使用intrinsic,当然是让编译器发出它们<代码>无符号位图=_mm_movemask_ps(_mm_castsi128_ps(v))/
int pos=\u bit\u scan\u forward(位图)。(或者你的编译器最喜欢的BSF本质:)那么要么你的示例从实际代码中过度简化(使用
+1
/
-1
而不是你的实际范围),要么你有一个bug,因为我认为它完全等同于只检查精确的相等性。但是好的,你会想要偏移量作为
int
无符号int
,所以这很好,
movmskps
/
bsf
正是你想要的。顺便说一句,这实际上可能不是任何东西的副本!我找不到任何其他带有
[x86]代码的SO帖子:\u mm\u movemask\u ps\u BitScanForward
。movemask->bitscan是一个非常有名的习惯用法,至少我认为是这样。你会发现它最像libc
memchr
/
strchr
。通常,人们只想知道是否有任何或所有元素满足某个条件,而不是哪一个,或者使用
movemask
结果作为整数索引,但我真的很惊讶我没有找到该代码的现有答案。但是它的asm和C版本在一天内就发布了!如果我有时间的话,我可以打一个答案。