所有新的AVX-512 FP转换指令都提供截断和电流舍入模式版本,这对压缩转换有意义; EVEX取整模式覆盖是only available for ZMMM vectors,而不是XMM/YMM。 我有点惊讶,他们费心用一个与vcvtsd2usi分开的操作码来制作vcvttsd2usi,而不是仅仅用VCVTSD2USI r64, xmm1/m64{rz-sae}的一个别名来覆盖舍入模式,以便向零截断。(您也可以覆盖为Nearest、Upward或Downward)。这样做的副作用是抑制该指令的FP异常,因此他们可能希望支持通过检查MXCSR标志来检测不准确或溢出转换的代码。
3条答案
按热度按时间fjnneemd1#
无耻地使用Janus的答案作为模板(毕竟我真的很喜欢C++):
在i7上使用
gcc -march=native -O3
生成,因此这是使用最多(包括)-mavx
。uint2float
生成的,反之亦然,正如预期的那样,长转换只是对大于263-1的数字有一个特殊情况。mm5n2pyu2#
下面是GCC生成的代码。我把它们封装在函数中,但是你可以很容易地去掉堆栈处理。并不是所有的都使用SSE来做实际的工作(ulonglong转换没有),如果你找到相应的指令,请告诉我。Clang生成的代码几乎一样。
以下是奖励点数(转换为整数):
这些函数从堆栈中获取输入并通过堆栈返回。如果在函数结束时需要XMM寄存器中的结果,可以使用movd/movq将其从堆栈中获取到XMM。如果函数返回的是双精度型,则结果为-0x8(%ebp)。如果它是浮点数,则结果为-0x4(%ebp)。Ulonglongs的长度为双精度数,而int的长度为浮点数。
第一个PLL:存储整数并截断
FISTTP使用截断(chop)作为舍入模式将ST中的值转换为有符号整数,将结果传输到目标,然后弹出ST。FISTTP接受字、短整数和长整数目标。
福康米:比较浮点值并设置EFLAGS
对寄存器ST(0)与ST(i)的内容执行无序比较,并根据比较结果设置EFLAGS寄存器中的状态标志ZF、PF及CF(请参阅下表)。比较时忽略零的符号,因此-0.0等于+0.0。
46qrfjad3#
另请参阅 * How to efficiently perform double/int64 conversions with SSE/AVX? *,了解有限范围或全范围的压缩转换技巧。另请参阅 Strange uint32_t to float array conversion,了解编译器实现该转换的策略分析。关于此问题的其他答案仅显示编译器生成的代码,而不讨论其工作原理。
在AVX-512中,浮点型/双精度型与无符号64位整数之间的转换指令非常等效。此答案主要针对双精度型与uint64_t之间的转换,但
vcvtuqq2ps
(压缩uint64_t到压缩单精度)和类似的指令确实存在,vcvtusi2sd xmm1, xmm2, r/m64{er}
只在64位模式下可用。使用SSE 1中同样不便的合并到某个寄存器语义,而不是零扩展到新的xmm。float
或double
* 至 *uint64_t
(带AVX-512 F)AVX-512 F增加了对FP与无符号整数(标量
vcvttsd2usi
或压缩)之间的转换以及 * 压缩 * 与64位整数之间的转换(有符号或无符号,例如vcvttpd2uqq
压缩双精度或vcvttps2uqq
将float 32转换为uint64_t)的支持。在AVX-512之前,使用32位无符号整数的标量转换在64位模式下或x87下很容易,使用非负64位有符号整数的零扩展。但即使在64位模式下,64位无符号整数也是一个问题。
vcvttsd2usi eax, xmm0
在32或64位模式下工作,使用AVX-512。(或ss
版本;浮点型与双精度型)vcttvsd2usi rax, xmm0
当然只能在64位模式下使用AVX-512。因此,我们可以改用压缩转换,因为在32位模式下不会阻止64位SIMD整数元素工作。我不确定高半部分中的垃圾是否代表了一个次正规浮点数/双精度浮点数,我猜可能不会,因为将其舍入为整数与一个微小的正规化值没有什么不同。
或者直接存储到存储器
vmovq [esp], xmm1
中。要使用当前舍入模式而不是截断,请在助记符中省略额外的
t
。(如果您没有更改MXCSR,则默认舍入模式是最接近的,并将even作为平局。)所有新的AVX-512 FP转换指令都提供截断和电流舍入模式版本,这对压缩转换有意义; EVEX取整模式覆盖是only available for ZMMM vectors,而不是XMM/YMM。
我有点惊讶,他们费心用一个与
vcvtsd2usi
分开的操作码来制作vcvttsd2usi
,而不是仅仅用VCVTSD2USI r64, xmm1/m64{rz-sae}
的一个别名来覆盖舍入模式,以便向零截断。(您也可以覆盖为Nearest、Upward或Downward)。这样做的副作用是抑制该指令的FP异常,因此他们可能希望支持通过检查MXCSR标志来检测不准确或溢出转换的代码。