我试图详细了解当分支被错误预测时,skylake CPU管道的各个阶段中的指令会发生什么,以及从正确的分支目标开始执行指令的速度如何。
因此,我们在这里将两个代码路径标记为红色(一个已预测但未实际采用)和绿色(一个已取得但未预期)。所以问题是: 1.在红色指令开始被丢弃之前,分支必须经过管道多远(以及在管道的哪个阶段被丢弃)? 2.绿色指令(从分支到达的流水线阶段来看)多久才能开始执行?
我看了看Agner Fogg的文件和许多讲义,但这些地方并不清楚。
答案 0 :(得分:5)
分支执行单元(在端口0和6上)实际上是检查FLAGS或间接分支地址的条件分支还是间接分支。我认为,恢复将在执行单元发现后立即开始,而无需等待其退役。 (这是我的最佳猜测/理解,不一定得到英特尔优化手册的支持。)
分支预测+推测执行使数据依赖与控制依赖脱钩,但是分支uop本身确实对EFLAGS或间接地址输入具有数据依赖。
p0上的分支单元只能运行未预测的JCC联播(或宏融合的JCC联播),但是这些是常见的。 p6上的分支单元是“主要”单元,用于处理已采取的分支。
对于直接分支(jmp rel8/rel32
/ call rel32
),可以在解码时检查预测并重新引导取回阶段,也许会使前端停滞不前,但是我认为永远不需要触发任何一种恢复在后端。来自错误路径的Uop永远不会为直接无条件分支发出。有用于管道转向的性能计数器。
分支错误预测可以使用分支顺序缓冲区快速恢复,这与通常在例外情况When an interrupt occurs, what happens to instructions in the pipeline?上回滚到退出状态不同。有关管道如何将一切视为投机直到退休的信息,请参阅Out-of-order execution vs. speculative execution。
根据David Kanter's Sandybridge microarch writeup:
Nehalem增强了分支错误预测的恢复能力,该错误预测已被延续到Sandy Bridge中。一旦发现分支预测错误,内核就可以在知道正确的路径后立即重新开始解码,与此同时无序的机器正在从错误推测的路径中清除错误。以前,直到管道完全刷新后,解码才能恢复。
这是由分支顺序缓冲区启用的“快速恢复”功能,可对有条件和间接分支指令上的重新命名状态进行快照,即使在正常程序中,这些指令也可能会预测错误。但是异常和内存排序机器清除的成本更高。它们确实会发生(尤其是页面错误),但是它们很少见并且更难优化。
快速恢复的关键在于,早在ROB + RS(调度程序)中的错误分支之前的
如果不进行快速恢复,我认为ROB中的所有 微词都将被丢弃(即所有未退休的微词)。这里可能有一些中间立场,例如保留已经从ROB分支但已离开调度程序的分支开始执行的微指令。我不知道Merom / Conroe到底做了什么。
相关:Characterizing the Branch Misprediction Penalty是一篇有趣的论文,介绍了分支丢失和长缓存丢失如何与ROB交互。它基于简化的管道模型,但在我看来,它的发现可能适用于Skylake。