嵌套分支和推测执行会发生什么?

C. *_*nto 6 cpu-architecture nested-if speculative-execution branch-prediction

好吧,所以我知道,如果特定的条件分支有一个需要时间来计算的条件(例如内存访问),CPU 会假定一个条件结果并沿着该路径推测执行。但是,如果沿着该路径弹出另一个缓慢的条件分支(当然,假设第一个条件尚未解决并且 CPU 无法提交更改),会发生什么情况?难道CPU只是在猜测里面猜测吗?如果最后一个条件预测错误但第一个条件没有预测会发生什么?难道只是一路回滚吗?

我正在谈论这样的事情:

if (value_in_memory == y){
   // computations
   if (another_val_memory == x){
      //computations
   }
}
Run Code Online (Sandbox Code Playgroud)

Bee*_*ope 4

推测执行是执行的常规状态,而不是乱序 CPU 在看到分支时进入,然后在分支不再运行时离开的特殊模式。

如果您考虑到不仅仅是分支可能会出错,而且许多指令(包括访问内存的指令、它们的输入值都有限制等),就更容易看出这一点。因此,任何严重的无序执行都意味着不断的推测,并且 CPU 是围绕这个想法建立的。

因此,从这个意义上说,“嵌套分支”最终并不特殊。

现在,现代 CPU 有多种方法可以快速恢复分支预测错误,比其他类型的故障恢复速度更快1。例如,它们可以对某些分支处的寄存器映射状态进行快照,以允许在分支位于重排序缓冲区的头部之前开始恢复。由于在所有分支上创建快照并不总是可行,因此可能需要复杂的启发式方法来决定在何处拍摄快照。

我提到最后一部分是因为这是嵌套分支可能很重要的一种方式:当有大量分支正在运行时,您可能会遇到一些与出于恢复目的而跟踪这些分支相关的微架构限制。有关更多详细信息,您可以查看“分支顺序缓冲区”的专利(针对英特尔技术,但毫无疑问还有其他技术)。


1基本的恢复方法是继续执行,直到出错的指令是下一个退出的指令,然后丢弃所有较新的指令。在分支错误预测的情况下,这意味着您实际上可能会遭受两个或多个错误预测,只有其中最旧的一个实际生效:例如,较年轻的分支错误预测,并且在执行到该分支时(此时可以发生恢复),另一个分支发生错误预测。发生错误预测,因此较年轻的最终会被丢弃。

  • @PeterCordes - 是的,这可能部分是语义上的。_Something_ 需要跟踪这一点,因为物理寄存器需要在某个时刻被释放,但它不一定是 RAT,其基本工作只是跟踪 _current_ 映射以支持重命名。由于 RAT 是关键单周期重命名循环上高度移植的东西,因此保持其尽可能紧凑是有意义的。完全映射可以在 PRRT(退休后回收表)之类的东西中进行跟踪,并且这个东西可能会更慢,因为退休一条指令实际上可能需要几个... (2认同)
  • ...周期(好吧,从逻辑上讲,有一个周期,在此期间指令退出,但在所有资源完全释放之前可能会发生额外的工作)。不过,你的观点仍然成立——无论跟踪发生在 RAT 本身,还是发生在可能属于或不属于 RAT 一部分的其他地方,该信息都必须恢复,所以我将编辑答案。 (2认同)