流水线和分支指令
Posted
技术标签:
【中文标题】流水线和分支指令【英文标题】:Pipeline and branch instructions 【发布时间】:2015-09-09 21:58:25 【问题描述】:假设程序中 20% 的指令是分支指令。跳转的静态预测假设跳转不会发生。
我应该在两种情况下找到执行时间:30% 的分支发生时和 70% 的分支发生时 我还应该找出一种情况与另一种情况相比的加速比,并以百分比表示。
问题是,我如何在这里找到执行时间?我通常会找到管道在不同阶段分离的执行时间,并且每个阶段都有时间......
编辑:这不是家庭作业。我在我的计算机体系结构教科书中找到了这个,它不是一个熟悉的练习。
【问题讨论】:
【参考方案1】:这个问题听起来像家庭作业,但值得讨论。
我们假设有一个总是预测 NOT TAKEN 的 static 分支预测器。这是早期 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 指令的执行阶段,我们评估条件并检测必须采用分支。然而,由于分支预测器策略,我们已经获取指令0xF2
和0xF3
并解码0xF2
。流水线被刷新,并在下一个时钟周期正确获取分支目标。从流水线中可以看出,我们浪费了 2 个时钟周期来获取和解码不会执行的指令。这 2 个时钟周期称为分支惩罚,在计算程序的执行时间时必须将它们考虑在内。
分支预测器的世界在现实中要复杂得多。存在更详细的静态分支预测器,例如,总是将前向跳转预测为 TAKEN,而后向跳转预测为 NOT TAKEN。为了减少 分支惩罚 周期,处理器通常使用分支目标缓冲区 (BTB),它是一个小型缓存,用于存储最近执行的 JUMP 指令的目标。如果没有 BTB,要将分支预测为 TAKEN,我们必须等到解码阶段,其中指令被识别为 JUMP 并且目标地址被解码。与此同时,我们已经获取了一条指令,然后将被刷新。另一方面,使用 BTB,我们可以在 Fetch 阶段进行分支预测:如果程序计数器在 BTB 中,我们知道 2
-
获取的指令是一个分支
我们有它的目标地址
所以如果可以预测分支并且如果预测为TAKEN,我们可以获取它的目标而不会受到任何惩罚。 现代处理器还采用动态分支预测器,这些预测器使用复杂的策略以及一些额外的缓冲区来避免错误预测。
【讨论】:
以上是关于流水线和分支指令的主要内容,如果未能解决你的问题,请参考以下文章