提问者:小点点

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


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

假设你有这样的东西:

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

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


共1个答案

匿名用户

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

所有对外部世界有任何影响的操作(即在核心之外是可观察的),只有在各自的指令被停用和提交后才会执行。在CPU在核心之外有一些专用缓冲以防止推测状态泄漏的情况下,可能会存在一些小例外,但效果是相同的——即使操作在内部执行,直到它被提交时才能被观察到。存储到内存、端口输出、断点或任何其他可观察的操作都包括在内。

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

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

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

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