1

我正在阅读有关分支预测的内容,我想知道分支预测器是否会“推测性地”执行任何类型的指令。特别是,我想知道它是否会与硬件通信。

假设你有这样的东西:

while (true) {
   if (condition)
      SendPacketOverNetwork()
   DoSomethingElse()
}

(在汇编级别, if 之后的第一条指令引发中断,或与硬件通信)。如果分支预测器碰巧“猜错了”,在这种情况下会发生什么?如果这不能发生,为什么?分支预测器将执行什么样的指令?我误解了分支预测器的作用吗?

4

1 回答 1

5

首先 - 分支预测器不执行任何操作,它只是告诉 CPU 下一条要获取和执行的指令是什么。然后 CPU 将获取下一组指令并将其插入其管道中,并开始执行它们。

所有对外部世界产生任何影响的操作(即在核心之外可观察到),仅在相应指令退出并提交后执行。在 CPU 在内核外部有一些专用缓冲以防止推测状态泄漏的情况下,可能存在一些小异常,但效果是一样的 - 即使操作是在内部执行的,直到这一点才能观察到它在哪里提交。存储到内存、端口、断点或任何其他可观察的操作都包括在内。

在分支错误预测时,推测状态被刷新并且机器中的任何虚假结果,包括比错误预测分支更年轻的所有操作都被回滚(在通常通过排序缓冲区管理的无序 CPU 上)。确切的细节当然取决于实际的微架构。由于提交是按顺序执行的(即使执行是无序的),它们充当一个收敛点 - 错误预测分支的执行必须在管道中的该点之前完成,因此在任何年轻指令的退休和提交(它们通常被认为是该分支的“阴影”)。因此,任何外部可观察的操作都无法执行,除非它比错误预测的分支更早。

示例(在故障机器上,因为这是更有趣的情况):

op1   |         exec          retire     
op2   |    exec                 retire    
branch|            exec           retire   
op3   |   exec                      retire 
op4   |          exec                 retire
store |                                 retire    dispatch
        ---------------------------> Time

如果分支在执行时发现它的预测是错误的,则保证在它们的退休/提交或管道中的任何后续操作(包括执行任何较年轻的存储)之前刷新下一条指令。在更简单的有序机器中,执行本身是有序的,因此分支将在任何较年轻的指令执行之前执行(并且分支解析将是已知的)。

于 2014-05-15T14:21:31.530 回答