if (a < 901)比 快吗if (a <= 900)?
if (a < 901)
if (a <= 900)
与这个简单的示例不完全一样,但循环复杂代码的性能略有变化。我想这必须与生成的机器代码有关,以防万一。
不,在大多数架构上它不会更快。您没有指定,但在 x86 上,所有积分比较通常都将在两条机器指令中实现:
test
cmp
EFLAGS
Jcc
jne
ZF = 0
jz
ZF = 1
jg
ZF = 0 and SF = OF
示例(为简洁而编辑)编译为$ gcc -m32 -S -masm=intel test.c
$ gcc -m32 -S -masm=intel test.c
if (a < b) { // Do something 1 }
编译为:
mov eax, DWORD PTR [esp+24] ; a cmp eax, DWORD PTR [esp+28] ; b jge .L2 ; jump if a is >= b ; Do something 1 .L2:
和
if (a <= b) { // Do something 2 }
mov eax, DWORD PTR [esp+24] ; a cmp eax, DWORD PTR [esp+28] ; b jg .L5 ; jump if a is > b ; Do something 2 .L5:
因此,两者之间的唯一区别是指令jg与jge指令。两者将花费相同的时间。
jge
我想解决没有任何迹象表明不同的跳转指令需要相同的时间的评论。这个问题有点难以回答,但我可以给出以下内容:在Intel Instruction Set Reference中,它们都被组合在一个通用指令下Jcc(如果满足条件则跳转)。在优化参考手册的附录 C. 延迟和吞吐量中进行了相同的分组。
延迟— 执行内核完成构成指令的所有 μop 的执行所需的时钟周期数。 吞吐量——在发布端口可以再次自由地接受相同指令之前需要等待的时钟周期数。对于许多指令,一条指令的吞吐量可能远低于其延迟
延迟— 执行内核完成构成指令的所有 μop 的执行所需的时钟周期数。
吞吐量——在发布端口可以再次自由地接受相同指令之前需要等待的时钟周期数。对于许多指令,一条指令的吞吐量可能远低于其延迟
的值为Jcc:
Latency Throughput Jcc N/A 0.5
附上以下脚注Jcc:
条件跳转指令的选择应基于第 3.4.1 节“分支预测优化”的建议,以提高分支的可预测性。当分支预测成功时,延迟jcc实际上为零。
jcc
因此,英特尔文档中的任何内容都不会将一条Jcc指令与其他指令区别对待。
如果考虑用于实现指令的实际电路,可以假设在 中的不同位上会有简单的 AND/OR 门EFLAGS,以确定是否满足条件。因此,一条指令测试两位的时间没有理由比一条只测试一位的指令花费更多或更少的时间(忽略门传播延迟,它远小于时钟周期。)
编辑:浮点
这也适用于 x87 浮点:(与上面的代码几乎相同,但使用double而不是int.)
double
int
fld QWORD PTR [esp+32] fld QWORD PTR [esp+40] fucomip st, st(1) ; Compare ST(0) and ST(1), and set CF, PF, ZF in EFLAGS fstp st(0) seta al ; Set al if above (CF=0 and ZF=0). test al, al je .L2 ; Do something 1 .L2: fld QWORD PTR [esp+32] fld QWORD PTR [esp+40] fucomip st, st(1) ; (same thing as above) fstp st(0) setae al ; Set al if above or equal (CF=0). test al, al je .L5 ; Do something 2 .L5: leave ret