【问题标题】:How does branch prediction interact with the instruction pointer分支预测如何与指令指针交互
【发布时间】:2019-01-27 06:41:15
【问题描述】:

据我了解,在处理器流水线的开头,指令指针(指向下一条要执行的指令的地址)在获取后由分支预测器更新,以便随后可以获取这个新地址下一个循环。

但是,如果在流水线的早期修改了指令指针,这不会影响当前可能依赖于旧指令指针值的执行阶段的指令吗?比如在做call时,需要将当前EIP压入栈中,但是在分支预测过程中更新指令指针时,这不会受到影响吗?

【问题讨论】:

  • 在许多流水线体系结构中,程序计数器是假的,软件可以看到的具有正确的值。执行真正繁重的工作的逻辑使用了一些到许多其他指令指针地址,一个或多个分支预测计算,用于获取内存的实际指针等。Arm 是一个简单的程序计数器,程序计数器提前两条指令很久没有这样了,管道随着预测而变深。但是我们仍然有一个 r15,它给出了指令集中设计的结果。
  • 像 EIP 这样的可用(伪)寄存器对于正在使用的指令集将具有正确的值,而与用于实际获取的任何锁存地址或组合地址无关。

标签: assembly x86 cpu cpu-architecture branch-prediction


【解决方案1】:

您似乎假设整个 CPU 内核只使用一个物理 EIP 寄存器。

这是行不通的,因为每条可能发生异常的指令都需要知道自己的地址。或者当外部中断到达时,CPU 可以决定在任何指令之后服务中断,从而使该中断成为架构 EIP。在长模式 (x86-64) 中,还有 RIP 相对寻址模式,因此 call 并不是唯一需要当前程序计数器作为数据的指令。

一个简单的流水线 CPU 可能对每个流水线阶段都有一个 EIP。

现代的超标量乱序 x86 将 EIP(或 RIP)与每个执行中的指令(或者可能是每个 uop)相关联;但多 uop 指令的所有 uop 都与其他,因此指令不能部分退出。)

与架构状态的其他部分(例如 EFLAGS、EAX 等)不同,该值在解码后是静态已知的。实际上甚至早于即时值;在预解码阶段检测指令边界(或在 L1i 缓存中标记),以便将多条指令并行馈送到多个解码器。

早期获取/解码阶段可能只跟踪 16 字节或 32 字节获取块的地址,但在解码后,我假设内部 uop 表示中有一个地址字段。对于非分支指令,它可能只是与前一个(以节省空间)的一个小偏移量,所以如果需要它可以计算出来,但我们在这里深入研究实现细节。乱序执行维护了以程序顺序运行的指令的错觉,它们确实按顺序发出和退出(进入/离开内核的乱序执行部分)。

相关:x86 registers: MBR/MDR and instruction registers 基于对玩具 CPU 的研究做出了类似的错误假设。也没有保存机器代码字节的“当前指令”寄存器。有关 OoO / 流水线 CPU 的更多信息,请参阅我的答案中的更多链接。


分支预测必须在块被解码之前工作。即假设我们刚刚在地址 abc 处获取了一个块,我们需要预测下一个要获取的块。即预测必须预测一个 16 字节指令块中是否存在跳转,这些指令将被并行解码。

相关:Why did Intel change the static branch prediction mechanism over these years?

【讨论】:

  • 现代超标量无序 x86 有一个与每条指令关联的 EIP(或 RIP)”是不是有点误导?我相信EIP 就像执行 uop 时的任何其他输入寄存器一样 - 即使用 EIP 的微架构值。
  • @MargaretBloom:不是;它不会存储在寄存器文件中,因为它在解码时对于每条指令都是静态已知的,并且不能作为输出。 控制依赖与数据依赖的处理方式不同。不过,我确实改写了那句话,因为它听起来和我想说的不太一样。
  • 大多数指令从来不需要知道自己的IP,至少以有效的方式,所以完全有可能地址不与每条指令一起存储,而只是以某种不一定快速的方式追溯计算,如果发生中断或异常或其他情况。尽管像call 或 rip-relative 之类的直接使用 IP 的指令仍然会在接近解码时间时填充它。正如您所指出的,这涉及到实现细节,我只是在猜测。
  • 顺便说一句,我认为获取/解码单元几乎必须计算预测的“准确”地址,而不是使用像 32 字节这样的更大粒度,因为(a)从解码开始你已经需要知道块中的正确偏移量,以便您可以正确解码指令,并且还因为您需要形成正确的连续指令流,并且(b)预测器本身需要实际地址才能进行下一次预测,因为可能有几个一个块内的分支。所以(a)表示粗略预测的窗口很小,(b)表示它可能为零。
  • 可能预测器实际上并不像我在 (b) 中建议的那样运行 - 即,它们的“最紧密”循环仅在块级别进行预测,然后它们细化目标以提供给解码器。这意味着他们会被同一块中具有不同目标和模式的多个分支所欺骗,并且可以通过软件进行测试。
猜你喜欢
  • 1970-01-01
  • 2019-03-10
  • 2014-03-04
  • 2014-12-02
  • 2013-12-31
  • 2015-03-31
  • 2021-01-29
  • 2014-01-25
  • 1970-01-01
相关资源
最近更新 更多