如何解决x86-SSE中四个压缩单精度浮点数到无符号双字的转换
在带有SSE扩展的x86中,是否可以将四个压缩的单精度浮点值转换为四个双字?
最接近的指令为 CVTPS2PI ,但不能在两个xmm寄存器上执行,而应指定为CVTPS2PI MM,XMM/M64
。如果我想要类似<conversion_mnemonic> XMM,XMM/M128
的东西怎么办?
谢谢。 伊曼。
解决方法
x86在带有vcvtps2udq
(https://www.felixcloutier.com/x86/vcvtps2udq)的AVX512之前没有对FP unsigned的本机支持。对于标量,通常只转换为64位带符号(cvtss2si rax,xmm0
)并取其低32位(在EAX中),但这不是SIMD的选择。
没有AVX-512,理想情况下,您可以使用签名转换(cvtps2dq
)并获得相同的结果。即如果您的浮点数为非负数且INT_MAX (2147483647.0
)。
请参阅How to efficiently perform double/int64 conversions with SSE/AVX?以获得相关的double-> uint64_t转换。如果需要的话,完整范围的应该可以从double-> uint64_t到float-> uint32_t进行修改。
另一种可能性(对于32位浮点型-> uint32_t)只是在FP中将范围转换为有符号,然后以整数形式返回。 INT32_MIN ^ convert(x + INT32_MIN)
。但这会为小整数引入FP舍入,因为INT32_MIN在-2 24 .. 2 24 范围之外,其中float
可以表示每个整数。例如5
将在转换过程中四舍五入到2 8 的最接近倍数。因此,这是不可用的;您需要尝试直接转换和范围内转换,并且仅当直接转换为您提供0x80000000
时才使用范围内转换。 (也许使用直接转换结果作为SSE4 blendvps
的混合控件?)
对于float-> int32_t的压缩转换,有SSE2 cvtps2dq xmm,xmm/m128
docs。 ({cvttps2dq
会被截断地转换为0,而不是当前的默认舍入模式(最近的舍入模式,如果尚未更改的话)。)
任何小于-0.5的负浮点将转换为-1或更低的整数;作为uint32_t
的位模式代表了一个巨大的数字。超出-2 31 .. 2 31 -1范围的浮点数将转换为英特尔的“整数不确定”值0x80000000
。
如果找不到,只有cvtps2pi将转换签名注册为MMX寄存器,您需要更好的搜索位置:
- https://stackoverflow.com/tags/sse/info-链接
- https://www.felixcloutier.com/x86/ x86指令集列表。
- https://www.officedaytime.com/simd512e/simd.html-按类别/功能列出的指令列表
- https://software.intel.com/sites/landingpage/IntrinsicsGuide/-为仅公开单个指令功能的内在函数列出了asm指令助记符。通常,最好是用内在函数编写C而不是用asm手工编写,尤其是在您不了解诸如
cvtps2dq
和cvttps2dq
之类的相对常见/简单的指令的情况下。 - https://agner.org/optimize/-他的asm优化指南中有关于SIMD的一章,其中包含各种数据移动指令的便捷表。
- How can I convert an XMM register of single-precision floats to integers?-指向正确方向的指针,但仅涵盖有符号转换。我没有找到完全相同的副本。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。