我目前正在查看CPU管道的各个部分,它们可以检测分支错误预测。我发现这些是:
我知道2和3检测到了什么,但我不明白在BTB中检测到了什么错误预测。 BAC检测BTB错误地预测非分支指令的分支的位置,其中BTB未能检测到分支,或者BTB错误预测了x86 RET指令的目标地址。执行单元评估分支并确定它是否正确。
在分支目标缓冲区中检测到哪种类型的误预测?究竟在这里发现了什么错误预测?
我能找到的唯一线索是英特尔开发者手册第3卷(底部的两个BPU CLEAR事件计数器):
BPU在错误地认为是错误的情况下预测了一个分支 没带。
这似乎意味着预测并非“同步”,而是“异步”,因此“在错误地假设之后”??
更新:
罗斯,这是CPU分支电路,来自最初的英特尔专利(如何用于“阅读”?):
我没有在任何地方看到“分支预测单位”?阅读本文的人会认为“BPU”是将BTB电路,BTB缓存,BAC和RSB组合在一起的一种懒惰方式吗?
所以我的问题仍然存在,哪个组件会引发BPU CLEAR信号?
答案 0 :(得分:8)
这是一个很好的问题!我认为它造成的混乱是由于英特尔奇怪的命名方案,这些方案经常超出学术界的标准。我会尽力回答你的问题,并澄清我在评论中看到的困惑。
首先。我同意在标准计算机科学术语中,分支目标缓冲区不是分支预测器的同义词。然而,在英特尔术语中,分支目标缓冲区(BTB)[大写字母]是特定的东西,包含预测器和分支目标缓冲区高速缓存(BTBC),它只是一个分支指令表及其在所采用结果上的目标。这个BTBC是大多数人所理解的分支目标缓冲区[小写]。那么什么是分支地址计算器(BAC),如果我们有BTB,为什么还需要它?
因此,您了解现代处理器分为多个阶段的管道。无论这是一个简单的流水线处理器还是一个乱序的超级处理器,第一阶段通常是 fetch 然后 decode 。在 fetch 阶段,我们所拥有的只是程序计数器(PC)中包含的当前指令的地址。我们使用PC从内存加载字节并将它们发送到 decode 阶段。在大多数情况下,我们增加PC以加载后续指令,但在其他情况下,我们处理控制流指令,可以完全修改PC的内容。
BTB的目的是猜测PC中的地址是否指向分支指令,如果是,那么PC中的下一个地址应该是什么?没关系,我们可以使用条件分支的预测器和下一个地址的BTBC。如果预测是正确的,那太好了!如果预测错了,那么呢?如果BTB是我们唯一的单位,那么我们必须等到分支到达管道的问题 / 执行阶段。我们必须冲洗管道并重新开始。但不是每个情况都需要这么晚才解决。这是分支地址计算器(BAC)的用武之地。
BTB用于管道的 fetch 阶段,但BAC驻留在 decode 阶段。一旦我们获取的指令被解码,我们实际上有更多可用的信息。我们知道的第一条新信息是:“我提取的指令实际上是分支?”在获取阶段,我们不知道,BTB只能猜测,但在解码阶段我们知道肯定。当实际上指令不是分支时,BTB可能预测分支;在这种情况下,BAC将暂停获取单元,修复BTB,并重新正确地重新获取。
unconditional relative
和call
等分支怎么样?这些可以在解码阶段验证。 BAC将检查BTB,查看BTBC中是否有条目并将预测器设置为始终预测已采用。对于conditional
个分支,BAC无法确认它们是否被采用,但是它可以至少验证预测的地址并在地址预测错误的情况下纠正BTB。有时BTB根本不会识别/预测分支。 BAC需要纠正此问题并向BTB提供有关此指令的新信息。由于BAC没有自己的条件预测器,它使用一种简单的机制(采用向后分支,不采用前向分支)。
有人需要确认我对这些硬件计数器的理解,但我认为它们意味着以下内容:
BACLEAR.CLEAR
会递增
作业和解码中的BAC可以修复它。BPU_CLEARS.EARLY
是
当 fetch 决定(错误地)加载下一个时,会递增
在BTB预测它应该实际加载之前的指令
取而代之的是路径。这是因为BTB需要多个周期, fetch 使用该时间推测性地加载连续的指令块。这可能是因为英特尔使用两个BTB,一个快速,另一个更慢但更准确。需要更多周期才能获得更好的预测。这解释了为什么在BTB中检测到错误预测的惩罚是2/3周期,而在BAC中检测到错误预测的惩罚是8个周期。