分支预测器推测地执行什么样的指令



我正在阅读关于分支预测的文章,我想知道分支预测器是否会"推测"地执行任何类型的指令。特别是,我想知道它是否会,例如,与硬件通信。

让我们假设你有这样的东西:

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

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

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

所有对外部世界有任何影响的操作(即在核心之外可观察到的操作),只有在相应的指令退役并提交后才会执行。如果CPU在核心之外有一些专用的缓冲来防止推测状态泄漏,则可能存在一些小的例外,但效果是一样的——即使操作是在内部执行的,在提交之前也无法观察到它。存储到内存、输出、断点或任何其他可观察的操作都包括在内。

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

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

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

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

最新更新