相当于 Ceil , Floor 的汇编语言

Assembly Language equivalent to Ceil , Floor

ceil、floor 的 x86 等价物是什么? 我不能特别google 相应的说明。 等价物不一定是一条指令,尽管一条指令是优选的。

单指令 floor/ceil 仅适用于 SSE4.1 roundsd / roundpd,并且仅适用于 XMM 而不是旧版 x87。


对于 x87,您设置当前舍入模式,然后使用 frndint. (http://www.ray.masmcode.com/tutorial/fpuchap1.htm 显示 RC 位在 x87 控制字中的位置)。可用的舍入模式是最近偶数(默认)、+Inf(ceil)、-Inf(floor)和零(trunc)。

完成后别忘了将舍入模式设置回来。

显然 frndint 在某些 CPU (https://agner.org/optimize) 上很慢,因此实际上可以更快地转换为整数并返回 fistp / fild(仍然有适当设置舍入模式)。但这仅适用于可以表示为带符号的 64 位整数的 FP 值(假设您使用 qword 内存操作数)。您可以改为添加/减去一个适当的幻数(以使值非常大并强制四舍五入)。同样,这可能需要设置舍入模式。

当然,如果您想要 (int)floor(x),那么肯定fistp 并根据需要设置舍入模式。

使用 SSE3,您可以使用 fisttp 向零截断(添加它是为了加速 C float->int 在代码中的转换,尽管 SSE 可用,但仍然希望使用旧版 x87)。

floor == trunc 对于非负值,因此您可以利用有效的 fisttp 或 SSE XMM 截断来处理这种情况。


对于 SSE4.1,对于 XMM 寄存器中的标量 double,您将使用 roundsd 舍入到最接近的整数值 double 以及您选择的由立即操作数指定的舍入模式。 (不是转换,只是像 frndint 这样的 double->double 舍入,所以它适用于任何值)。提供压缩和标量单精度和双精度版本。

对于 SSE4.1,roundsd + cvtsd2si(int)floor(x) 的最佳选择。或者 如果你知道你的值是非负的,你可以只使用 SSE2 cvttsd2si。注意 "truncate" 的额外 t。 (对于单精度或使用 cvtpd2dq 的打包 SIMD 相同)