c - 使用 SIMD 右移 32 位压缩负数
问题描述
我正在编写一些 SSE/AVX 代码,并且有一项任务是将压缩的有符号 32 位整数除以 2 的补码。当值为正时,此移位可以正常工作,但是由于移位了符号位,因此对于负值会产生错误的结果。
是否有任何 SIMD 操作可以让我移动保留符号位的位置?谢谢
解决方案
对于 16 位和 32 位元素大小,SSE2/AVX2 可以选择算术1与逻辑右移。(对于 64 位元素,在 AVX512 之前只有逻辑可用)。
使用_mm_srai_epi32
( psrad
)代替_mm_srli_epi32
( psrld
)。
请参阅Intel 的内在函数指南以及 SSE 标签 wiki https://stackoverflow.com/tags/sse/info中的其他链接。(如果需要,将其过滤以排除 AVX512,因为这些天它非常混乱,所有 3 种尺寸的所有蒙面版本......)
或者只是查看 asm 指令集参考,其中包括具有它们的指令的内在函数。在http://felixcloutier.com/x86/index.html中搜索“算术”可以找到您想要的转换。
请注意a
=arithmetic 与l
=logical,而不是通常的 intrinsic 命名方案epu32
for unsigned。asm 助记符简单且一致(例如 Packed Shift Right Arithmetic Dword = psrad
)。
算术右移也可用于 AVX2 变量移位 ( vpsravd
,以及立即移位的所有元素唯一变量版本。
脚注1:
算术右移移动符号位的副本,而不是零。
这正确地实现了 2 的补码符号除法,并舍入到负无穷大,这与您从 C 符号除法中得到的零截断不同。查看 asm 输出int foo(int a){return a/4;}
以了解编译器如何根据移位实现有符号除法语义。
推荐阅读
- c# - 有没有办法读取语言配置文件并将其转换为对象?
- python - 我想在数据帧上应用分组并通过其值大于任何给定数字的平均值对其进行过滤
- django - Django 找不到静态文件
- image - Symfony 4 - DomPDF - 使用 VichUploader 显示图像?
- javascript - 我怎样才能在每个时期之后执行彼此之后的功能
- android - 无法与 BottomNavigationBar 结合显示 Column (Flutter 1.9.1)
- javascript - D3 地图投影不显示地图
- html - 如何使用 css 创建箭头形状标题?
- java - 为什么会出现这个错误 java.lang.IllegalStateException?
- python - 如何提示用户选择 0-90 之间的间隔并存储为浮点数?