相当于 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 相同)
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 相同)