当Skylake CPU(处理器)预测错误分支时会发生什么?

12

我正在努力详细了解Skylake CPU管道各个阶段中指令在分支预测错误时发生的情况,以及正确分支目标的指令可以多快开始执行。因此,我们将这里的两个代码路径标记为红色(被预测但实际并未采取)和绿色(被采取但未被预测)。所以问题是: 1. 分支在管道中需要走多远,红色指令才开始被丢弃(它们被丢弃的管道阶段是哪些)? 2. 多快(从分支达到的管道阶段来看)可以开始执行绿色指令?

我查看了Agner Fogg的文档和许多课堂笔记,但没有找到这些要点的明确说明。

1个回答

15

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

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

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


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


分支预测错误可以通过分支顺序缓冲快速恢复,与通常的异常回滚到退役状态不同(中断发生时,流水线中的指令会发生什么?)。有关流水线如何将所有内容视为推测性操作直到退役,请参见乱序执行与推测执行

根据David Kanter的Sandybridge微体系结构写作

Nehalem增强了从分支预测错误中恢复的能力,并延续到了Sandy Bridge。一旦发现分支预测错误,核心就能够在正确路径已知的同时重新启动解码,同时乱序机器正在清除来自错误推测路径的uops。以前,解码直到流水线完全刷新才会恢复。

(Skylake's BOB有48个条目,因此有48个尚未执行的分支正在进行中。我认为BOB条目应该在分支uop执行时释放,而不需要保留分配直到退役。)

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

快速恢复的关键点是,在被丢弃的后续uop正在执行并且前端重新定向到正确地址时,已经在ROB + RS(调度程序)中的误预测分支之前的uop可以继续执行。因此,如果JCC uop的输入足够早地准备好,如果CPU可以在恢复时处理长依赖链,那么大部分分支失误惩罚都可以隐藏。例如,从具有相当长的循环传递依赖链的循环退出,或任何瓶颈,而不是总uop吞吐量或端口6瓶颈。请参见通过提前计算条件来避免停顿流水线

如果没有快速恢复,我认为ROB中的所有 uops都将被丢弃(即所有未退役的uops)。这里可能有一些折衷方案,例如保留已经执行的分支之前在ROB中但已离开调度程序的uops。我不知道Merom/Conroe确切做了什么。


相关内容:分析分支预测错误的惩罚是一篇有趣的论文,讨论了分支预测错误和长缓存错误如何与ROB交互。虽然它基于一个简化的流水线模型,但我认为它的发现可能适用于Skylake。


执行端口如何在前一条指令尚未退役时知道EFLAGS寄存器的状态?执行端口如何知道预测是错误的,即它如何知道原始预测,它是如何与指令相关联的? - Lewis Kelsey
@LewisKelsey:原始预测被编码在uop中。 在Haswell和之后的处理器上,甚至有一个额外的分支执行单元位于端口0,只能处理预测为未采取的分支。 jcc 对EFLAGS具有数据依赖性,就像adcsetc一样。 它不需要等待产生它的指令退役,只需执行即可。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接