【问题标题】:Using SIMD to right shift 32 bit packed negative number使用 SIMD 右移 32 位压缩负数
【发布时间】:2019-01-22 00:39:29
【问题描述】:

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

【问题讨论】:

    标签: c sse avx mmx


    【解决方案1】:

    SSE2/AVX2 可选择算术1 与 16 位和 32 位元素大小的逻辑右移。 (对于 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 助记符简单且一致(例如 Packed Shift Right Arithmetic Dword = psrad)。


    算术右移也可用于 AVX2 变量移位 (vpsravd,以及立即移位的所有元素一个变量版本。


    脚注 1:

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

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

    【讨论】:

    • 非常感谢您的快速响应!想知道我怎么错过了那条指令..
    • @Isso:我也是:P。但是其他人赞成您的问题,所以我认为答案可能不像我那样明显或容易搜索。 (即使您知道正确的术语,在内在函数指南中搜索“算术”也找不到,只能在 asm 指南中找到。)
    猜你喜欢
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多