x86-SSE中四个压缩单精度浮点数到无符号双字的转换

问题描述

在带有SSE扩展的x86中,是否可以将四个压缩的单精度浮点值转换为四个双字? 最接近的指令为 CVTPS2PI ,但不能在两个xmm寄存器上执行,而应指定为CVTPS2PI MM,XMM/M64。如果我想要类似<conversion_mnemonic> XMM,XMM/M128的东西怎么办?

谢谢。 伊曼。

解决方法

x86在带有vcvtps2udqhttps://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寄存器,您需要更好的搜索位置:

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...