C语言 使用 SIMD 右移 32 位打包负数



我正在编写一些SSE/AVX代码,并且有一个任务是将打包的有符号32位整数除以2的补码。当值为正时,此偏移工作正常,但是由于移动符号位,它会产生负值的错误结果。
是否有任何 SIMD 操作可以让我移动保留符号位的位置?谢谢

SSE2/AVX2 可以选择 16 位和 32 位元素大小的算术1与逻辑右移。 (对于 64 位元素,在 AVX512 之前只有逻辑元素可用(。

使用_mm_srai_epi32(psrad(而不是_mm_srli_epi32(psrld(。

请参阅英特尔内部函数指南,以及 SSE 标签 wiki https://stackoverflow.com/tags/sse/info 中的其他链接。 (如果需要,请将其过滤以排除AVX512,因为如今所有3种尺寸的所有蒙版都非常混乱...

或者只需查看 asm 指令集参考,其中包括具有它们的指令的内部函数。 在 http://felixcloutier.com/x86/index.html 中搜索"算术"可以找到您想要的班次。

请注意 =算术与al=逻辑,而不是通常的无符号epu32的内部命名方案。 asm 助记符简单且一致(例如打包移位右算术字 =psrad(。


算术右移也可用于AVX2可变移位(vpsravd,以及即时移位的单变量全元素版本。


脚注1:

算术右移在符号位的副本中移位,而不是零

这正确地实现了 2 的补码有符号除以 2 的幂,四舍五入到负无穷大,这与你从 C 有符号除法得到的截断到零不同。 查看int foo(int a){return a/4;}的 asm 输出,了解编译器如何在移位方面实现带符号除法语义。

最新更新