【问题标题】:How to understand macro `likely` affecting branch prediction?如何理解影响分支预测的宏“可能”?
【发布时间】:2020-07-16 17:22:57
【问题描述】:

我注意到如果我们知道控制流是真还是假的可能性很大,我们可以告诉编译器,例如,在Linux内核中,有很多likelyunlikely,实际上是由@987654323实现的@ 由gcc 提供,所以我想了解它是如何工作的,然后检查了那里的程序集:

  20:branch_prediction_victim.cpp ****             if (array_aka[j] >= 128)
 184                            .loc 3 20 0 is_stmt 1
 185 00f1 488B85D0              movq    -131120(%rbp), %rax
 185      FFFDFF
 186 00f8 8B8485F0              movl    -131088(%rbp,%rax,4), %eax
 186      FFFDFF
 187 00ff 83F87F                cmpl    $127, %eax
 188 0102 7E17                  jle     .L13

那么对于__builtin_expect

  20:branch_prediction_victim.cpp ****             if (__builtin_expect((array_aka[j] >= 128), 1))
 184                            .loc 3 20 0 is_stmt 1
 185 00f1 488B85D0              movq    -131120(%rbp), %rax
 185      FFFDFF
 186 00f8 8B8485F0              movl    -131088(%rbp,%rax,4), %eax
 186      FFFDFF
 187 00ff 83F87F                cmpl    $127, %eax
 188 0102 0F9FC0                setg    %al
 189 0105 0FB6C0                movzbl  %al, %eax
 190 0108 4885C0                testq   %rax, %rax
 191 010b 7417                  je      .L13
  • 188 - setg 设置是否大于,这里设置是否大于什么?
  • 189 - movzbl 移动零扩展字节到长,我知道这一移动 %al%eax
  • 190 - testq 按位或然后设置 ZF CF 标志,对吗?

我想知道它们如何影响分支预测,并提高性能,三个额外的指令,需要更多的周期对吗?

【问题讨论】:

  • 使用setcc然后以这种方式测试reified标志是一种愚蠢的模式,表明代码可能是在低优化设置下编译的,你能举一个可重现的例子吗?
  • 查看您实际编译的代码会很有帮助。正如哈罗德所说,看起来根本没有优化,这一切都毫无意义。没有人关心未经优化的代码编译速度。

标签: performance assembly x86 branch-prediction


【解决方案1】:

setcc 读取 FLAGS,在这种情况下由 cmp 之前设置。阅读the manual

这看起来您忘记启用优化,所以 __builtin_expect 只是在寄存器中创建一个 0 / 1 布尔值并在它非零时分支,而不是在原始 FLAGS 条件上分支。 不要看未优化的代码,它总是很烂。

线索是:作为likely的一部分的braindead布尔化,并使用RBP作为带有movq -131120(%rbp), %rax的帧指针从堆栈中加载j


likely 通常不会改进运行时分支预测,它会改进代码布局以在事情按照源代码所说的方式进行时最大限度地减少采用的分支数量会(即快速案例)。因此,它提高了常见情况下的 I-cache 局部性。例如编译器将把事情安排好,所以常见的情况是一个不采用的条件分支,只是失败了。这使得超标量流水线 CPU 中的前端变得更容易,这些 CPU 可以一次获取/解码多条指令。继续直线抓取是最简单的。

likely 实际上可以让编译器使用分支而不是 cmov 用于您知道是可预测的情况,即使编译器启发式(没有配置文件引导优化)会出错。相关:gcc optimization flag -O3 makes code slower than -O2

【讨论】:

    猜你喜欢
    • 2020-02-12
    • 2023-03-12
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2023-03-15
    • 2015-08-12
    • 2019-12-13
    相关资源
    最近更新 更多