【问题标题】:Branch "anticipation" in modern CPUs现代 CPU 中的分支“预期”
【发布时间】:2015-09-17 12:52:51
【问题描述】:

我最近在考虑现代 CPU 中的分支预测。 据我了解,分支预测是必要的,因为在管道中执行指令时,我们不知道在进行分支之前条件操作的结果。

既然我知道现代乱序 CPU 可以按任意顺序执行指令,只要满足它们之间的数据依赖关系,我的问题是,CPU 能否以分支目标已经存在的方式重新排序指令CPU 需要走分支的时间就知道了,因此可以“预测”分支方向,所以完全不需要猜测?

CPU 也可以这样转:

do_some_work();
if(condition()) //evaluating here requires the cpu to guess the direction or stall
   do_this();
else
   do_that();

到这里:

bool result = condition();
do_some_work(); //bunch of instructions that take longer than the pipeline length
if(result) //value of result is known, thus decision is always 100% correct
   do_this();
else
   do_that();

一个特定且非常常见的用例是迭代集合,其中退出条件通常是循环不变的(因为我们通常不会在迭代集合时修改集合)。

我的问题是现代一般 CPU 可以做到这一点,如果可以,哪些特定的 CPU 内核已知具有此功能?

【问题讨论】:

  • 更多的是与编译器优化有关,而不是CPU。
  • 我认为分支预测有点低级和“愚蠢”,因为它对程序的状态了解不多,只了解基本的指令输入。所以不,我不相信 CPU 会这样做。
  • 据我了解,分支预测器在很大程度上取决于编译器,并且它以一种易于预测分支的方式组织代码。
  • 您可能会发现 Rami Sheikh 等人的“控制流解耦”(2012,ACM page;PDF)很有趣。
  • 嗯,不,听起来你在期待一个 cpu 内核来解决停机问题。已经完成,RISC 内核曾经有一个“分支槽”,一个额外的指令,总是在一个分支之后执行以购买延迟。像垃圾一样的规模,是您今天的机器中没有 RISC 内核的重要原因。

标签: c optimization hardware cpu-architecture branch-prediction


【解决方案1】:

请记住,分支预测在管道中很早就完成了,您仍然没有解码指令,并且您无法解决数据依赖关系,因为您不知道使用哪个寄存器。您可能会在某个地方记住这一点,但这不是 100%(因为您的存储容量/时间将受到限制),所以这几乎就是您的正常分支预测器所做的 - 仅根据指令指针推测目标。

但是,提早进行条件评估很有用,它在过去已经完成,并且主要是一种编译器技术,但可能会通过一些硬件支持得到增强(例如 - hoisting branch condition)。分支错误预测的主要性能影响是评估延迟,因为这些天的分支恢复本身非常短。

这意味着您可以通过编译器仅提升条件并提前计算,而无需任何硬件修改来减轻大部分损失 - 如果您错误预测分支(以及现代预测器的可能性通常很低),但您会在解码分支本身时立即知道(因为数据将提前准备好),因此损坏将仅限于很少的指令,使其进入管道经过那个分支。

虽然能够提升评估并不简单。在大多数情况下,编译器可能能够检测到是否存在任何直接的数据依赖关系(在您的示例中使用do_some_work()),但在大多数情况下会有。循环不变量是编译器今天已经移动的第一件事。此外,一些最难预测的分支依赖于一些内存获取,你通常不能假设内存会保持不变(你可以,之后进行一些特殊检查,但大多数常见的编译器不会这样做)。无论哪种方式,它仍然是一种编译器技术,而不是分支预测的根本变化。

【讨论】:

    【解决方案2】:

    进行分支预测是因为 CPU 的指令获取器需要知道在分支指令之后要获取哪些指令,而这直到分支执行后才知道。

    如果处理器有 5 级管道(大多数处理器有更多),如下所示:

    1. 指令获取
    2. 指令解码
    3. 注册阅读
    4. ALU 执行
    5. 注册回写

    提取器将停止 3 个周期,因为直到 ALU 执行周期之后才能知道分支结果。

    提升分支测试条件并不能解决从获取分支指令到执行的延迟问题。

    【讨论】:

      猜你喜欢
      • 2019-07-24
      • 2012-09-03
      • 1970-01-01
      • 2012-07-11
      • 2023-03-12
      • 2012-01-04
      • 2018-11-24
      • 2012-06-23
      • 2017-11-10
      相关资源
      最近更新 更多