我正在读关于分支预测,我想知道分支预测器是否会“推测性地”执行任何类型的指令。特别是,我想知道它是否会与硬件进行通信。
我们假设你有类似的东西:
while (true) {
if (condition)
SendPacketOverNetwork()
DoSomethingElse()
}
(在汇编级别,if之后的第一条指令引发中断,或与硬件通信)。如果分支预测器恰好“猜错”,在这种情况下会发生什么?如果这不可能发生,为什么?分支预测器将执行什么样的指令?我误解了分支预测器的作用吗?
答案 0 :(得分:5)
首先 - 分支预测器不执行任何操作,它只是告诉CPU下一条获取和执行的指令是什么。然后,CPU将获取并将下一组指令插入其管道,然后开始执行它们。
所有对外部世界产生影响的操作(即在核心外部都可观察到),只有在相应的指令退役并提交后才能执行。在CPU在核心外部有一些专用缓冲以防止投机状态泄漏的情况下可能存在一些小的例外,但效果是相同的 - 即使操作在内部执行,也不能观察到它承诺的地方。存储,存储,断点或任何其他可观察的操作的存储都包括在内。
在分支错误预测时,推测状态被刷新,并且机器中的任何虚假结果,包括比错误预测分支更小的所有操作都被回滚(在通常通过排序缓冲区管理的无序CPU上)。具体细节当然取决于实际的微架构。 由于提交是按顺序执行的(即使执行是无序执行的),它们也可以作为收敛点 - 错误预测分支的执行必须在管道中的那个点之前完成,因此先于任何年轻教学的退休和承诺(他们经常被认为是"在该分支的阴影中)。因此,任何外部可观察的操作都无法执行,除非它比错误预测的分支更旧。
示例(在无序机器上,因为那是更有趣的情况):
op1 | exec retire
op2 | exec retire
branch| exec retire
op3 | exec retire
op4 | exec retire
store | retire dispatch
---------------------------> Time
如果分支在执行时发现其预测错误,则保证在退休/提交之前或管道之后的任何事情(包括执行任何较年轻的商店)之前刷新下一条指令。在一个更简单的有序机器中,执行本身是有序的,因此在任何更年轻的指令执行之前,将执行分支(并且分支解析将是已知的)。