流水线和分支指令

Posted

技术标签:

【中文标题】流水线和分支指令【英文标题】:Pipeline and branch instructions 【发布时间】:2015-09-09 21:58:25 【问题描述】:

假设程序中 20% 的指令是分支指令。跳转的静态预测假设跳转不会发生。

我应该在两种情况下找到执行时间:30% 的分支发生时和 70% 的分支发生时 我还应该找出一种情况与另一种情况相比的加速比,并以百分比表示。

问题是,我如何在这里找到执行时间?我通常会找到管道在不同阶段分离的执行时间,并且每个阶段都有时间......

编辑:这不是家庭作业。我在我的计算机体系结构教科书中找到了这个,它不是一个熟悉的练习。

【问题讨论】:

【参考方案1】:

这个问题听起来像家庭作业,但值得讨论。

我们假设有一个总是预测 NOT TAKENstatic 分支预测器。这是早期 SPARC 和 MIPS 实现的分支预测器类型。这样的分支预测器总是获取程序中的下一条顺序指令。

我还假设我们有一个简化的 4 阶段管道,由 Fetch (F)、Decode (D)、Execute (E) 和 Write Back (W) 组成。考虑以下简化的汇编程序:

        ...
0xF1:   JUMP <condition>, 0xF4
0xF2:   ADD r1, r2, r3
0xF3:   ADD r3, r4, r1
0xF4:   ADD r1, r2, r3

当分支被正确预测时,管道会正常运行。问题是当分支被错误预测时,管道会发生什么。在我们的例子中,对应于 JUMP 指令 (0xF1) 的条件得到验证的情况。

0xF1:  F  D  E  W
0xF2:     F  D  X
0xF3:        F  X  
0xF4:           F

cycle  1  2  3  4

在 JUMP 指令的执行阶段,我们评估条件并检测必须采用分支。然而,由于分支预测器策略,我们已经获取指令0xF20xF3 并解码0xF2。流水线被刷新,并在下一个时钟周期正确获取分支目标。从流水线中可以看出,我们浪费了 2 个时钟周期来获取和解码不会执行的指令。这 2 个时钟周期称为分支惩罚,在计算程序的执行时间时必须将它们考虑在内。

分支预测器的世界在现实中要复杂得多。存在更详细的静态分支预测器,例如,总是将前向跳转预测为 TAKEN,而后向跳转预测为 NOT TAKEN。为了减少 分支惩罚 周期,处理器通常使用分支目标缓冲区 (BTB),它是一个小型缓存,用于存储最近执行的 JUMP 指令的目标。如果没有 BTB,要将分支预测为 TAKEN,我们必须等到解码阶段,其中指令被识别为 JUMP 并且目标地址被解码。与此同时,我们已经获取了一条指令,然后将被刷新。另一方面,使用 BTB,我们可以在 Fetch 阶段进行分支预测:如果程序计数器在 BTB 中,我们知道 2

    获取的指令是一个分支 我们有它的目标地址

所以如果可以预测分支并且如果预测为TAKEN,我们可以获取它的目标而不会受到任何惩罚。 现代处理器还采用动态分支预测器,这些预测器使用复杂的策略以及一些额外的缓冲区来避免错误预测。

【讨论】:

以上是关于流水线和分支指令的主要内容,如果未能解决你的问题,请参考以下文章

分支预测

CPU指令的流水线执行

最快的CPU指令

超标量技术

ARM Cortex A9的流水线介绍

ARM 程序集中分支上的延迟结果指令会发生啥情况?