X86 为什么英特尔这些年来改变了静态分支预测机制?

X86 为什么英特尔这些年来改变了静态分支预测机制?,x86,compiler-construction,intel,cpu-architecture,branch-prediction,X86,Compiler Construction,Intel,Cpu Architecture,Branch Prediction,据我所知,Intel近年来实施了几种静态分支预测机制: 80486年龄:始终不服用 奔腾4时代:向后推进/向前未推进 更新的CPU,如常春藤桥,哈斯韦尔已经变得越来越无形,见 英特尔似乎不想再谈论它了,因为我在英特尔文档中找到的最新资料是大约十年前写的 我知道静态分支预测远不如动态分支预测重要,但在很多情况下,CPU将完全丢失,程序员(带编译器的)通常是最好的指导。当然,这些情况通常不是性能瓶颈,因为一旦频繁执行分支,动态预测器就会捕获它 由于Intel在其文档中不再明确说明动态预测机制,G

据我所知,Intel近年来实施了几种静态分支预测机制:

  • 80486年龄:始终不服用

  • 奔腾4时代:向后推进/向前未推进

  • 更新的CPU,如常春藤桥,哈斯韦尔已经变得越来越无形,见

英特尔似乎不想再谈论它了,因为我在英特尔文档中找到的最新资料是大约十年前写的

我知道静态分支预测远不如动态分支预测重要,但在很多情况下,CPU将完全丢失,程序员(带编译器的)通常是最好的指导。当然,这些情况通常不是性能瓶颈,因为一旦频繁执行分支,动态预测器就会捕获它

由于Intel在其文档中不再明确说明动态预测机制,GCC的内置函数expect()只能从热路径中删除不太可能的分支

我不熟悉CPU设计,也不知道英特尔目前使用的静态预测器的具体机制,但我仍然觉得英特尔最好的机制应该是清楚地记录他的CPU“当动态预测器出现故障时,我计划去哪里,向前或向后”,因为通常程序员是当时最好的向导


更新:
我发现你提到的话题逐渐超出了我的知识范围。这里涉及到一些动态预测机制和CPU内部细节,我无法在两三天内了解它们。因此,请允许我暂时退出您的讨论并重新充电
这里仍然欢迎任何答案,也许会帮助更多的人

我的理解是,在当前的设计中,现代的分支方向预测器总是使用最近分支的已执行/未执行历史索引到一个条目。(这可能会将单个分支的状态扩展到许多内部状态,从而可以预测非常复杂的模式,如10元素BubbleSort。)

CPU不尝试检测混叠,只使用它找到的预测来决定条件分支的执行/不执行。i、 分支方向预测始终是动态的,而不是静态的

但是,在分支解码之前,仍然需要进行目标预测,以防止前端停滞。分支目标缓冲区通常会被标记,因为被别名化的其他分支的目标不太可能有用

因此,BTB未命中可能会让CPU决定使用静态预测,而不是在动态采取/未采取预测器中找到的任何预测。我们可能只是看到,让动态预测器经常漏掉以测量静态预测要困难得多

(我可能是在歪曲事实。现代的TAGE预测器也可以预测间接分支的复杂模式,所以我不确定他们是否尝试预测已采取/未采取,或者第一步是否总是尝试预测下一个地址,这是否是下一条指令……)


未执行的分支在正确预测的情况下仍然稍微便宜一些,因为前端可以更容易地在同一周期内从uop缓存中获取更早和更晚的指令。(Sandybridge系列中的uop缓存不是跟踪缓存;uop缓存线只能缓存x86机器代码连续块中的uop。)在高通量代码中,执行的分支可能是一个较小的前端瓶颈。它们通常还会将代码分散到更多的L1i和uop缓存线上


对于间接分支,“默认”分支目标地址仍然是下一条指令,因此在
jmp-rax
之后放一个
ud2
或其他东西以防止错误推测(尤其是在非代码中),如果您不能简单地将一个实际分支目标作为下一条指令(尤其是最常见的分支目标)


分支预测是一种“秘密调味品”,CPU供应商不会公布其详细信息。

英特尔实际上自己发布指令吞吐量/延迟/执行端口信息(通过IACA和一些文档),但实验测试非常简单(就像和已经做过的一样),所以即使他们想保密,英特尔也不能保密


分支预测成功率很容易用perf计数器来衡量,但要知道一个特定分支在一次特定执行中预测失误或没有预测失误的原因是非常困难的;即使是对一个分支的一次执行,也很难进行衡量,除非您使用
rdtsc
rdpmc
或其他工具来测试代码。

静态分支预测“英特尔优化手册”第3.4.1.3节中讨论的措辞如下:

  • 预测要采取的无条件分支
  • 预测不采用的条件远期分支
  • 预测要执行的条件向后分支
  • 预测不采用的间接分支
编译器可以相应地组织代码。同一部分说明如下:

英特尔核心微体系结构不使用静态预测 启发式。但是,要在Intel 64和IA-32之间保持一致性 处理器、软件应保持静态预测启发式 作为默认值

本声明表明,第3.4.1.3节已多年未更新

如果动态预测器无法预测所获取的字节之间是否存在分支指令,或者如果其缓冲区中发生未命中,则由于没有其他有意义的选择,因此获取单元将继续按顺序获取,从而有效地对未获取进行静态预测

但是,如果在指令队列单元中,在获取的字节流中有条件或间接分支指令,则