if( a < 901 )if( a <= 900 )快。

与这个简单示例并不完全一样,但是循环复杂代码的性能略有变化。我想这与生成的机器代码有关,以防万一。

最佳答案

不,在大多数架构上不会更快。您没有指定,但是在x86上,所有整数比较通常都将在两条机器指令中实现:


testcmp指令,用于设置EFLAGS
Jcc (jump) instruction,具体取决于比较类型(和代码布局):

jne-如果不相等则跳转-> ZF = 0
jz-如果为零(等于)则跳转-> ZF = 1
jg-如果更大则跳转-> ZF = 0 and SF = OF
(等等...)





示例(为简洁起见,已编辑)使用$ 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:


因此,两者之间的唯一区别是jgjge指令。两者将花费相同的时间。



我想指出的是,没有任何内容表明不同的跳转指令花​​费相同的时间。回答这个问题有些棘手,但是我可以提供以下信息:在Intel Instruction Set Reference中,它们都按照一条通用指令Jcc分组在一起(如果满足条件则跳转)。附录C.延迟和吞吐量中的Optimization Reference Manual下将相同的分组在一起。


  延迟-时钟所需的时钟周期数
  执行核心以完成所有形式的μop的执行
  一条指令。
  
  吞吐量—所需的时钟周期数
  等待发布端口可以自由接受相同的指令
  再次。对于许多指令,一条指令的吞吐量可以是
  大大少于其延迟


Jcc的值为:

      Latency   Throughput
Jcc     N/A        0.5


Jcc上有以下脚注:


  7)有条件跳转指令的选择应基于第3.4.1节“分支预测优化”的建议,以提高分支的可预测性。成功预测分支后,jcc的等待时间实际上为零。


因此,英特尔文档中的任何内容都不会与其他文档区别对待。

如果考虑用于实现指令的实际电路,则可以假定Jcc中不同位上将存在简单的AND / OR门,以确定是否满足条件。这样,没有理由测试一个两位的指令所花费的时间比一个测试一个位所花费的时间要长得多或更少(忽略门传播延迟,这比时钟周期要短得多)。



编辑:浮点数

x87浮点数也是如此:(与上面的代码几乎相同,但使用EFLAGS而不是double。)

        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

07-24 09:44