9

我试图详细了解当错误预测分支时 Skylake CPU 管道的各个阶段中的指令会发生什么,以及来自正确分支目标的指令可以多快开始执行。

因此,让我们将这里的两条代码路径标记为红色(预测的,但未实际采用的)和绿色(采用的,但未预测的)。所以问题是: 1. 在红色指令开始被丢弃之前分支必须经过管道多远(以及它们在管道的哪个阶段被丢弃)?2. 绿色指令多久可以开始执行(就分支到达的流水线阶段而言)?

我查看了 Agner Fogg 的文档和大量的讲义,但在这些要点上并不清楚。

4

1 回答 1

12

分支执行单元(在端口 0 和 6 上)实际上是检查 FLAGS 或间接分支地址的条件或间接分支。我认为一旦执行单元发现它,恢复就开始了,而无需等待它退休。(其中一些是我最好的猜测/理解,不一定得到英特尔优化手册的支持。)

分支预测 + 推测执行将数据依赖与控制依赖解耦,但分支 uop 本身确实对 EFLAGS 或间接地址输入有数据依赖。

p0 上的分支单元只能运行预测未采用的 JCC 微指令(或宏融合的 JCC 微指令),但这些很常见。p6 上的分支单元是处理已取分支的“主”单元。


对于直接分支(jmp rel8/rel32/ call rel32),可以在解码时检查预测并重新引导 fetch 阶段,这可能会使前端停滞,但我认为永远不需要在后端触发任何类型的恢复。永远不会为直接无条件分支发出来自错误路径的 Uop。有用于管道重新引导的性能计数器。


分支错误预测通过分支顺序缓冲区可以快速恢复,这与通常的异常回滚到退休状态不同:当中断发生时,流水线中的指令会发生什么?. 有关管道如何将所有内容视为投机直到退休的更多信息,请参阅乱序执行与投机执行

根据David Kanter 的 Sandybridge microarch 文章

Nehalem加强了从分支错误预测中的恢复,该错误预测已被转移到 Sandy Bridge。一旦发现分支预测错误,一旦知道正确的路径,核心就能够重新开始解码,同时乱序机器正在从错误推测的路径中清除 uops。以前,在管道完全刷新之前,解码不会恢复。

这是由分支顺序缓冲区启用的“快速恢复”,该缓冲区在条件和间接分支指令上快照重新命名状态,即使在正常程序中也会出现错误预测。但是异常和内存排序机器清除更昂贵。它们确实会发生(尤其是页面错误),但它们更罕见且更难优化。

快速恢复的关键在于,已经在 ROB + RS(调度程序)中的错误预测分支之前的微指令可以继续执行,而后来的微指令被丢弃,前端重新引导到正确的地址。因此,如果 JCC uop 的输入足够早地准备好,如果 CPU 在恢复时可以咀嚼长依赖链,则可以隐藏大部分分支未命中惩罚。例如,从带有适当长度循环的循环退出时的错误预测携带了 dep 链,或除总 uop 吞吐量或端口 6 瓶颈之外的任何瓶颈。请参阅通过提前计算条件来避免停止流水线

如果没有快速恢复,我认为ROB 中的所有微指令都将被丢弃(即所有未退休的微指令)。这里可能有一些中间立场,比如保留在 ROB 中但离开调度程序的分支之前已经执行的微指令。我不知道 Merom/Conroe 到底做了什么。


相关:Characterizing the Branch Misprediction Penalty是一篇关于分支未命中和长缓存未命中如何与 ROB 交互的有趣论文。它基于简化的管道模型,但在我看来,它的发现可能适用于 Skylake。

于 2018-06-22T17:02:14.157 回答