c++ - < 比 <= 快吗?

标签 c++ c performance assembly relational-operators

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(如果条件满足则跳转)。在 Optimization Reference Manual 下进行了相同的分组。 ,在附录 C 中。延迟和吞吐量。

Latency — The number of clock cycles that are required for the execution core to complete the execution of all of the μops that form an instruction.

Throughput — The number of clock cycles required to wait before the issue ports are free to accept the same instruction again. For many instructions, the throughput of an instruction can be significantly less than its latency

Jcc 的值为:

      Latency   Throughput
Jcc     N/A        0.5

Jcc 上有以下脚注:

  1. Selection of conditional jump instructions should be based on the recommendation of section Section 3.4.1, “Branch Prediction Optimization,” to improve the predictability of branches. When branches are predicted successfully, the latency of jcc is effectively zero.

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

如果考虑用于实现指令的实际电路,可以假设在 EFLAGS 的不同位上会有简单的 AND/OR 门,以确定是否满足条件。那么,一条指令测试两位的时间没有理由比一条只测试一位的时间多或少(忽略门传播延迟,它远小于时钟周期。)


编辑: float

这也适用于 x87 float :(与上面的代码几乎相同,但使用 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

关于c++ - < 比 <= 快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12135518/

相关文章:

c - 如何创建给定大小的文件?

python - 在 C++ 中更快执行两个程序的可能解释(与 Python 比较)?

html - Chrome 和 Opera 中的 Kinetic JS 性能问题

c++ - 在qt中从mpv单击鼠标

c++ - 在现代 C++ 中使用原始指针是不好的做法吗?

c - 如何将帧缓冲区对象绘制到默认帧缓冲区

python - 计算数组python中每个子字符串的数量

c++ - ivec4 作为顶点属性 Opengl ES 2.0

c++ - 在 C++ 中的共享库 (so) 中的共享内存中创建对象

C添加已由函数初始化的结构覆盖原始结构