ceil,floor在x86上相当于什么?我不能特别搜索相应的说明。等效可能不一定是一条指令,尽管一条指令是更可取的。
单指令层/天花板仅适用于SSE4.1roundsd
/ roundpd
,并且仅适用于XMM,不适用于旧版x87。
使用x87,设置当前的舍入模式,然后使用frndint
。 (frndint
显示RC位在x87控制字中的位置)。可用的舍入模式为最接近偶数(默认),朝向+ Inf(上限),朝向-Inf(底限)和接近零(trunc)。
完成后请不要忘记将舍入模式设置回。
显然,http://www.ray.masmcode.com/tutorial/fpuchap1.htm在某些CPU(frndint
)上较慢,因此实际上可以更快地将其转换为整数并以https://agner.org/optimize / fistp
进行转换(仍然适当地设置了舍入模式)。但这仅适用于可以表示为带符号的64位整数的FP值(假设您使用qword内存操作数)。您可以改为添加/减去适当的幻数(以使该值真正大而强制舍入)。同样,这可能需要设置舍入模式。
当然,如果您want fild
,那么肯定只是(int)floor(x)
,并根据需要设置了舍入模式。
使用SSE3,您可以使用fistp
截断为零(它被添加来加快C float-> int的代码转换,即使在SSE可用的情况下,它仍要使用旧版x87。]]
[fisttp
表示非负值,因此您可以在这种情况下利用有效的floor == trunc
或SSE XMM截断。
对于XMM寄存器中的标量fisttp
,使用SSE4.1,>您将使用double
舍入到最接近的整数值roundsd
,并选择由立即操作数指定的舍入模式。 (不是转换,而是像roundsd
一样进行double-> double四舍五入,因此适用于任何值)。提供打包和标量单精度和双精度版本。
对于SSE4.1,double
+ frndint
是roundsd
的最佳选择。或如果您知道您的值是非负数,则可以只使用SSE2 cvtsd2si
。注意“截断”的额外(int)floor(x)
。 (对于单精度或带有cvttsd2si
的压缩SIMD相同。)