繁体   English   中英

了解停顿和分支延迟时隙

[英]Understanding stalls and branch delay slots

我正在上一门计算机体系结构课程。 我从另一所大学那里找到了这个网站,该网站上有笔记和视频到目前为止对我有帮助: CS6810,犹他大学 我正在处理发布在该网站上的一些旧作业,尤其是这个作业。 我试图了解流水线和相关概念,特别是停顿和分支延迟时隙。

我现在正在看旧作业分配的第一个问题,不确定如何解决这些问题。

问题如下:

考虑下面的代码段,其中分支的使用时间为30%,而不是70%。

R1 = R2 + R3

R4 = R5 + R6

R7 = R8 + R9

如果R10 = 0,则分支到linex

R11 = R12 + R13

R14 = R11 + R15

R16 = R14 + R17

...

Linex:R18 = R19 + R20

R21 = R18 + R22

R23 = R18 + R21

...

考虑一个10阶段的有序处理器,其中在第一阶段提取指令,并且在三个阶段之后就知道分支结果。 在以下情况下估计处理器的CPI(假定处理器中的所有停顿都与分支相关,并且分支占所有已执行指令的15%):

  1. 在每个分支上,访存将停止,直到知道分支结果为止。

  2. 预测每个分支都不被采用,并且如果分支被采用,则错误提取的指令将被压缩。

  3. 处理器具有两个延迟槽,并且总是提取并执行分支之后的两条指令,并且

    3.1。 您找不到任何说明来填补延迟时间。

    3.2。 您可以在分支转移到延迟槽之前移动两条指令。

    3.3。 标签“ linex”后,您可以将两个指令移入延迟槽。

    3.4。 您可以在分支(原始代码中)之后立即将一条(注意:一条,而不是两条!)指令移入延迟槽。

我不确定如何开始研究这个问题。 我已经阅读了所有笔记并观看了该站点上的视频,并阅读了H&P书中的部分内容,但仍然对此问题感到困惑。 如果有人有时间,我将不胜感激有人帮助我解决这个问题。 我只需要知道如何开始概念化答案即可。

在所描述的流水线中,条件分支的方向和目标在第三个周期结束之前不可用,因此直到第四个周期开始之前,不能(确定地)获取分支之后的正确下一条指令。

设计1

处理分支后指令地址延迟可用性的一种明显方法就是等待。 这是设计1通过停顿两个周期来完成的工作(这等效于获取不属于实际程序的两个无操作)。 这意味着对于采用和未采用路径,都将浪费两个周期,就像编译器已插入两个无操作指令一样。

这是流水线的示意图(ST是停顿,NO是无操作,XX是取消的指令,UU是无用的指令,I1,I2和I3是分支之前的三个指令[按照原始程序顺序在填充任何延迟时隙之前],BI是分支指令,I5,I6和I7是分支指令之后的转移指令,I21,I22和I23是采用路径开始处的指令; IF是该指令获取阶段,DE被解码,BR是分支解析,S1是BR之后的阶段):

         Taken                  Not taken
         IF  DE  BR  S1 ...     IF  DE  BR  S1 ...
cycle 1  BI  I3  I2  I1         BI  I3  I2  I1
cycle 2  ST  BI  I3  I2         ST  BI  I3  I2
cycle 3  ST  ST  BI  I3         ST  ST  BI  I3
cycle 4  I21 ST  ST  BI         I5  ST  ST  BI
cycle 5  I22 I21 ST  ST         I6  I5  ST  ST

设计2

为避免必须在IF阶段结束时检测到分支的存在,并允许有时(在未使用的情况下)进行一些有用的工作,而不是让硬件有效地将无操作插入管道(即,在分支之后停止获取),硬件可以将该分支与其他任何指令一样对待,直到在第三条管道阶段中将其解决为止。 这是在预测所有分支都不被采用。 如果采用分支,则取消分支​​后提取的两条指令(有效地变为无操作)。 这是设计2:

         Taken                  Not taken
         IF  DE  BR  S1 ...     IF  DE  BR  S1 ...
cycle 1  BI  I3  I2  I1         BI  I3  I2  I1
cycle 2  I5  BI  I3  I2         I5  BI  I3  I2
cycle 3  I6  I5  BI  I3         I6  I5  BI  I3
cycle 4  I21 XX  XX  BI         I7  I6  I5  BI
cycle 5  I22 I21 XX  XX         I8  I7  I6  I5

设计3

总是预测不采用分支将在每次采用分支时浪费两个周期,因此开发了第三个机制来避免这种浪费-延迟分支。 在延迟分支中,硬件始终在分支之后执行(不取消)延迟时隙指令(示例中为两条指令)。 通过始终执行延迟时隙指令,简化了流水线。 编译器的工作是尝试用有用的指令填充这些延迟时间。

无论采用哪个路径,从分支之前(在没有延迟分支的程序中)获取的指令都是有用的(但是依赖关系可能会阻止编译器在分支之后调度任何此类指令)。 编译器可以使用来自采用或未采用路径的指令填充延迟槽,但是这样的指令不能是覆盖另一条路径(或在路径加入之后)使用的状态的指令,因为延迟槽指令不会被取消(与预测)。 (如果两条路径都连接在一起(对于if-then-else构造很常见),则可能会从连接点填充延迟槽;但是此类指令通常取决于连接之前至少一条路径中的指令,这种依赖性将阻止它们在延迟槽中使用。)如果编译器找不到有用的指令,则必须使用no-op填充延迟槽。

在情况3.1(延迟分支设计的最坏情况)下,编译器找不到任何有用的指令来填充延迟时隙,因此必须用no-op填充它们:

         Taken                  Not taken
         IF  DE  BR  S1 ...     IF  DE  BR  S1 ...
cycle 1  BI  I3  I2  I1         BI  I3  I2  I1
cycle 2  NO  BI  I3  I2         NO  BI  I3  I2
cycle 3  NO  NO  BI  I3         NO  NO  BI  I3
cycle 4  I21 NO  NO  BI         I5  NO  NO  BI
cycle 5  I22 I21 NO  NO         I6  I5  NO  NO

在性能上等效于设计1(停转两个周期)。

在情况3.2(延迟分支设计的最佳情况)下,编译器从分支之前发现了两条指令来填充延迟时隙:

         Taken                  Not taken
         IF  DE  BR  S1 ...     IF  DE  BR  S1 ...
cycle 1  BI  I1  ...            BI  I1  ...
cycle 2  I2  BI  I1  ...        I2  BI  I1 ...
cycle 3  I3  I2  BI  I1         I3  I2  BI  I1
cycle 4  I21 I3  I2  BI         I5  I3  I2  BI
cycle 5  I22 I21 I3  I2         I6  I5  I3  I2

在这种情况下,无论是否采用分支,所有流水线插槽均填充有有用的指令。 性能(CPI)与理想的管道相同,没有延迟的分支解析。

在情况3.3中,编译器使用来自所采用路径的指令填充了延迟时隙:

         Taken                  Not taken
         IF  DE  BR  S1 ...     IF  DE  BR  S1 ...
cycle 1  BI  I3  I2  I1         BI  I3  I2  I1
cycle 2  I21 BI  I3  I2         I21 BI  I3  I2
cycle 3  I22 I21 BI  I3         I22 I21 BI  I3
cycle 4  I23 I22 I21 BI         I5  UU  UU  BI
cycle 5  I24 I23 I22 I21        I6  I5  UU  UU

在未采用的路径中,I21和I22无效。 尽管它们实际上已执行(和更新状态),但未使用的路径(或路径的任何连接之后)不使用此状态。 对于未采用的路径,好像延迟槽已被无操作填充。

在情况3.4中,编译器只能从未采用的路径中找到一条安全指令,并且必须用no-op填充另一延迟槽:

         Taken                  Not taken
         IF  DE  BR  S1 ...     IF  DE  BR  S1 ...
cycle 1  BI  I3  I2  I1         BI  I3  I2  I1
cycle 2  I5  BI  I3  I2         I5  BI  I3  I2
cycle 3  NO  I5  BI  I3         NO  I5  BI  I3
cycle 4  I21 NO  UU  BI         I6  NO  I5  BI
cycle 5  I22 I21 NO  UU         I7  I6  NO  I5

对于采用的路径,将执行一条无用的指令和一项无操作,从而浪费了两个周期。 对于未采用的路径,将执行一个无操作,浪费一个周期。

计算CPI

在这种情况下,计算CPI的公式为:

%non_branch * CPI_non_branch + %branch * CPI_branch

CPI_branch通过考虑分支本身所花费的时间(baseCPI_branch)和分支被占用时的浪费周期的百分比,以及分支被浪费时未被浪费的周期的百分比来计算不采取。 因此,CPI_branch为:

baseCPI_branch + (%taken * wasted_cycles_taken) + 
                 (%not_taken * wasted_cycles_not_taken)

在理想的标量流水线中,每条指令占用一个周期,即每条指令的周期为1。在此示例中,非分流指令的行为就好像流水线是理想的(“处理器中的所有停顿与分支相关”),因此,每条非分支指令的CPI均为1。同样,baseCPI_branch(不包括来自停顿,无操作等的浪费周期)为1。

根据上面的管线图,可以确定在已采用和未采用路径中浪费的循环数。 该示例给出了分支的百分比以及已采用和未采用的分支百分比。

对于设计1,采用和未采用的路径都浪费2个周期,因此CPI_branch为:

1 + (0.3 * 2) + (0.7 *2) = 3

因此,CPI总和为:

(0.85 * 1) + (0.15 * 3) = 1.3

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM