我正在编写一些SSE / AVX代码,有一个任务是将打包的带符号的32位整数除以2的补码。当值为正时,此移位工作正常,但是由于移位符号位,因此对负值产生错误的结果。
是否有任何SIMD操作可让我移位以保留符号位的位置?谢谢
答案 0 :(得分:5)
SSE2 / AVX2可以选择算术 1 与逻辑右移。 (对于64位元素,在AVX512之前只有逻辑可用)。
使用_mm_srai_epi32
(psrad
)代替_mm_srli_epi32
(psrld
)。
请参见Intel's intrinsics guide和SSE标签Wiki https://stackoverflow.com/tags/sse/info中的其他链接。 (如果需要,可以将其过滤以排除AVX512,因为这几天所有3种尺寸的所有蒙版都非常混乱...)
或者只是看一下asm指令集参考,其中包括具有指令的内在函数。在http://felixcloutier.com/x86/index.html中搜索“算术”即可找到所需的班次。
请注意,a
=算术与l
=逻辑,而不是epu32
的无符号的通常内在命名方案。 asm助记符简单且一致(例如,压缩右移算术双字= psrad
)。
算术右移还可以用于AVX2可变移位(vpsravd
,以及即时移位的一元换所有元素版本。
脚注1:
算术右移符号位的副本而不是零。
这可以正确实现2的2的补码除法运算,并朝负无穷大舍入,这与从C的除法运算得到的向零截断不同。查看int foo(int a){return a/4;}
的asm输出,以了解编译器如何根据移位实现带符号的划分语义。