CSAPP:第四章——处理器体系结构(下)

四、流水线的通用原理

流水线化的一个重要特性就是提高了系统的吞吐量(throughput),也就是单位时间内服务的顾客总数,不过它也会轻微地增加延迟(latency),也就是服务一个用户所需要的时间。例如,自助餐厅里的一个只需要甜点的顾客,能很快通过一个非流水线化的系统,只在甜点阶段停留,但是在流水线化的系统中,这个顾客还需要经过沙拉、主材和饮料阶段,即使在这些阶段什么也不做。

4.1 计算流水线

1)非流水线化设计

图 a是一个非流水线化的硬件系统,它是由一些执行计算的组合逻辑和一个保存计算结果的寄存器组成的,输入信号进入组合逻辑,一段时间的延迟(300 ps,读作300皮秒)之后,输出某个信号并存放至寄存器,时钟信号控制在每个特定的时间间隔(20 ps)加载寄存器。
在这里插入图片描述
图 b图 a的一种称为流水线图的时序图,可发现,在开始下一条指令之前必须完成上一条指令,且延迟(从头到尾执行一条指令所需时间)为320 ps,所以可以从下面公式推算出这个系统的最大吞吐量(单位时间内CPU执行指令的总数)为3.12 GIPS,其中1 ns = 10E-9GIPS为每秒千兆条指令,也就是每秒十亿条指令。延迟和吞吐量互为倒数
在这里插入图片描述

2)流水线化设计

如下图所示,假设将上面系统分为3个阶段(A、B、C),每个阶段100 ps,然后在各个阶段放上流水线寄存器,这样每执行一条指令就需要三个完整的周期(A、B、C)。从图 b看,只要 I1 从 A 进入到B,就可以让 I2 进入阶段 A 了,每个时钟周期(120 ps),一条指令离开系统,一条新的进入。
在这里插入图片描述
在这个系统中,我们将时钟周期设为 100 + 20 = 120 ps,得到的吞吐量大约为 8.33 GIPS,因为处理一条指令需要 3 个时钟周期,所以这条流水线的延迟就是 3 * 120 = 360 ps。我们将系统吞吐量提高到原来的 8.33 / 3.12 = 2.67 倍,代价是增加了一些硬件,以及延迟的少量增加。延迟变大是由于增加的流水线寄存器的时间开销

4.2 流水线操作的详细说明

下图是上一节流水线设计的三阶段流水线的流水线图
在这里插入图片描述
下图跟踪了时刻 240 ~ 360 之间的电路活动,在时刻 240(点1)时钟上升之前,阶段 A 中计算的指令 I2 的值已经到达第一个流水线寄存器的输入,但是该寄存器的状态和输出还保持为指令 I1 在阶段 A 中计算的值,指令 I1 在阶段 B 中计算的值已经到达第二个流水线寄存器的输入;当时钟上升时,这些输入被加载到流水线寄存器中,称为寄存器的输出(点2),阶段 A 的输入被设置成发起指令 I3 的计算;然后信号传播可能会以不同的速率通过各个阶段的组合逻辑(点3);在时刻 360 之前,结果值到达流水线寄存器的输入(点4);当时刻 360 时钟上升时,各条指令会前进经过一个流水线阶段。
在这里插入图片描述

4.3 流水线的局限性

1)不一致的划分

4.1的流水线化其实是一个理想化设计,将一个系统分为三个阶段,每个阶段执行时间是原逻辑的三分之一,在现实设计中往往不是如此。下图将计算也划分为三个阶段,但是通过这些阶段的延迟从 50 ps150 ps 不等,通过所有阶段的延迟和仍然为 300 ps。不过,运行时钟的速率是由最慢的阶段的延迟限制的。流水线图表明,每个时钟周期,阶段 A 都会空闲 100 ps,而阶段 C 会空闲 50 ps,只有阶段 B(最慢阶段)会一直处于活动状态。我们必须将时钟周期设为 150 + 20 = 170 ps,得到吞吐量为 5.88 GIPS,由于时钟周期减慢了,延迟也增加到了 510 ps。所以由此来看,系统的吞吐量由系统的最慢阶段限制
在这里插入图片描述

2)流水线过深,收益反而下降

下图把计算分成了 6 个阶段,每个阶段需要 50 ps,在每对阶段之间插入流水线寄存器就得到一个六阶段流水线,这个系统的最小时钟周期为50 + 20 = 70 ps,吞吐量为 14.29 GIPS,通过将流水线的阶段数加倍,吞吐量与之前相比提升14.29 / 8.33 = 1.71倍。虽然将每个计算时钟的时间缩短了两倍,但是由于通过流水线寄存器的延迟,吞吐量并没有加倍,这个延迟便成了流水线吞吐量的一个制约因素,延迟占到了整个时钟周期的120 / 420 = 28.6 %
在这里插入图片描述
所以,设计处理器流水线时,核心思想就是阶段尽可能多(有15级或更多的),但是与寄存器交互的阶段尽可能少(减少寄存器延迟)

4.4 带反馈的流水线系统

带反馈的流水线系统指的是,正在执行的指令I1可能会和即将要执行的指令I2具有相关性,I1需要将自己的结果反馈给I2。其中I1I2的相关性包括相邻指令之间的数据相关,及控制流造成的顺序相关

指令相关主要包括数据相关、控制相关和结构相关。数据相关包括写后读(Read After Write,简称RAW)相关、读后写(Write AfterRead,简称WAR)相关和写后写(WriteAfter Write,简称WAW)相关。其中RAW相关是真正的数据相关,因为存在真正的数据传递关系;WAR相关和WAW相关又称为假相关或者名字相关,指令之间实际不存在数据传递。

下面三条指令,irmovq指令将它的结果存放在 %rax 中,然后addq指令要读这个值;而 addq 指令将它的结果存放在 %rbx中,mrmovq指令要读这个值。所以指令irmovqaddq以及addqmrmovq具有数据相关。
在这里插入图片描述
jne 指令产生了一个控制相关,因为条件测试的结果会决定要执行的新指令是 irmovq 指令还是 halt 指令。
在这里插入图片描述

五、Y86-64的流水线实现

这节的目的是创建一个流水线化的 y86-64 处理器。

5.1 SEQ+:重新安排计算阶段

SEQ作为实现流水线化设计的一个过渡步骤,现在须稍微调整一下它的五个阶段的顺序,使得更新 PC 阶段在一个时钟周期开始执行,而不是结束时才执行。调整后的硬件结构设计叫做SEQ+,如下图所示:
在这里插入图片描述
从图中得知,更新下一个PC的值可能会与当前指令的指令代码icode、分支信号Cnd、立即数valC以及从内存读出的值valM中的一个或多个有关,也可能与下一条指令的地址valP有关。将SEQ+的硬件结构和SEQ硬件结构做对比:

  • 在SEQ 中,PC 计算发生在时钟周期结束的时候,根据当前时钟周期计算出的信号值来计算 PC 寄存器的新值,也就是这些输出信号(icodeCnd等)并没有被物理寄存器保存起来。
  • 在 SEQ+ 中,创建状态寄存器来保存在一条指令执行过程中计算出来的信号(icodeCnd等),当一个新的时钟周期开始时,这些信号值通过同样的逻辑来计算当前指令的 PC。我们将这些寄存器标号为pIcodepCnd等,在任意给定的周期,它们保存的都是前一个周期中产生的控制信号。
  • SEQ+ 没有硬件寄存器来存放程序计数器,而是根据前一条指令保存下来的状态信息动态的计算PC。

5.2 插入流水线寄存器

创建一个流水线化的 y86-64 处理器(叫做PIPE-处理器)最初尝试。在 SEQ+ 的各个阶段之间插入流水线寄存器,如下图所示。流水线寄存器在该图中用黑色方框表示,每个流水线寄存器包括不同的字段,用白色方框表示。每个流水线寄存器可以存放多个字节和字。这里的白色方框代表实际的硬件组成,同 SEQ 和 SEQ+ 硬件结构中的不同。流水线寄存器按如下方式标号:

  • F:保存程序计数器的预测值
  • D:位于取指和译码阶段之间。它保存关于最新取出的指令的信息,即将由译码阶段进行处理
  • E:位于译码和执行阶段之间。它保存关于最新译码的指令和寄存器文件读出的值的信息,即将由执行阶段进行处理
  • M:位于执行和访存阶段之间。它保存最新执行的指令的结果,即将由访存阶段进行处理。它还保存关于处理条件转移的分支条件和分支目标的信息
  • W : 位于访存阶段和反馈路径之间,反馈路径将计算出来的值提供给寄存器文件写,而当完成 ret 指令时,它还要向 PC 选择逻辑提供返回地址
    在这里插入图片描述

下图是4条irmovq指令和1条halt指令通过此流水线的示例,图中描述了每条指令通过流水线各个阶段的行进过程,时间从左往右增大。上面一条数字表明各个阶段发生的时钟周期。例如,在周期1取出指令I1,然后它开始通过流水线各个阶段,到周期 5 结束后,其结果写入寄存器文件。在周期2取出指令 I2,到周期6结束后,其结果写回,以此类推。在最下面,给出了当周期为 5 时的流水线的扩展图,此时每个流水线阶段中各有一条指令。
在这里插入图片描述

5.3 对信号进行重新排列和标号

顺序实现 SEQ 和 SEQ+ 在一个时刻只处理一条指令,因此诸如 statsrcAvalE 这样的信号值有唯一的值。在流水线化的设计中(如图 4-41),由于各阶段之间插入了流水线寄存器,指令可并行执行,同一时间流水线不同的阶段可能处理不同的指令(如图 4-42周期5),所以诸如 statsrcAvalE 这样的信号每个阶段可能产生不一样的值。可以在信号名前加大写的流水线寄存器名字作为前缀,存储在流水线寄存器中的信号可以唯一地被标志,如D_stat。若需要引用某些在一个阶段内刚刚计算出来的信号,它们的命名是在信号名前面加上小写的阶段名的第一个字母作为前缀,如 m_stat

信号 M_statm_stat 的差别:

  • 在命名系统中,大写的前缀 D、E、M 和 W 指的是流水线寄存器,所以 M_stat 指的是流水线寄存器 M 的状态码字段。
  • 小写的前缀 f、d、e、m 和 w 指的是流水线阶段,所以 m_stat 指的是在访存阶段中由控制逻辑块产生出的状态信号。

在所有的指令中,只有call在访存阶段和跳转指令在执行阶段(当不需要进行跳转)需要 valP 的值,而这两类指令都不需要从寄存器文件中读出的值d_rvalA。因此可合并这两个信号,利用Select A块从来自流水线寄存器D的valP或从寄存器文件A端口中读出的值中选一个,作为流水线寄存器 E的值valA

5.4 预测下一个PC

流水线化设计的目的就是每个时钟周期都发射一条新指令,也就是说每个时钟周期都有一条新指令进入执行阶段并最终完成。要做到这一点,我们必须在取出当前指令之后,马上确定下一条指令的位置。但是如果取出的指令是条件分支指令,就需要等条件分支指令通过执行阶段,才能确定是否要选择分支。类似地,如果取出的指令是ret,要到指令通过访存阶段(ret指令:将PC的设置为当前栈顶存放的值),才能确定返回地址。除了条件转移和ret指令以外,calljmp指令的下一条指令的地址是指令中常数字valC,其他的所有指令都是valP(当前PC+当前指令长度)。

calljmp以及其他指令的下一条指令,都是确定的,但对于不确定的条件转移指令,我们需要预测 PC 的下一个值。我们既可以预测选择了分支,那么新 PC 值应为valC ,也可以预测没有选择分支,那么新 PC 值应为valP,具体如何预测取决于CPU对这一块硬件的设计。这种猜测分支方向并根据猜测开始取指的技术成为分支预测

常见分支预测策略:

  • 1)总是选择(always taken)策略,成功率大约为60%。
  • 2)从不选择(naver taken)策略,成功率大约为40%。
  • 3)反向选择、正向不选择(backword taken,forward no-taken)策略,当分支的地址比下一条地址低时预测选择分支,高时预测不选择分支,成功率大约为65%。这种策略的缘起是因为循环都是后向分支结束的,切循环会执行很多次。

ret指令能否预测呢?显然是不行的,在Y86-64中,ret的返回地址位于栈顶,是一个不确定的值,所以无法预测,只能等其通过访存阶段,读取到值才能更新PC。

5.5 流水线冒险

带反馈的流水线系统可知,相邻指令之间可能具有数据相关或控制相关,这些相关可能会导致流水线计算错误,称为冒险(hazard)。同相关一样,冒险也分为两类:数据冒险(data hazard)和控制冒险(control hazard)。

如下图周期 5 内流水线的行为,此时 addq 指令将要通过译码阶段,读取操作数寄存器。但是,第一条irmovq指令中寄存器 %rdx 的写仍处在写回阶段,第二条irmovq指令对寄存器 %rax 的写还处在访存阶段,因此,addq 指令会得到两个错误的操作数。这就是典型的数据冒险。
在这里插入图片描述

5.5.1 数据冒险解决办法

1)用暂停来避免数据冒险

暂停(stalling)是避免冒险的一种常用技术,暂停时,处理器会在某个阶段停止流水线中一条或多条指令,直到冒险条件不再满足。如让一条指令停顿在译码阶段,直到产生它的源操作数的指令通过了写回阶段,这样我们的处理器就能避免数据冒险。这种机制实现容易,性能欠佳,会严重降低CPU整体的吞吐量。
在这里插入图片描述
2)用转发来避免数据冒险

暂停势必引起流水线执行效率的降低,有一种新的技术和暂停配合使用可以更高效的解决问题。如下图中周期6,D阶段(译码)逻辑发现,寄存器 %rax 是操作数 valB 的源寄存器,而W阶段(写回)将要写回的目的寄存器也是%rax,所以只要简单地通过多路选择器直接把W阶段的W_valE作为D阶段valB的输入,就能避免暂停。这种将结果值直接从一个流水现阶段传到较早阶段的技术成为数据转发(data forwarding,简称转发,或旁路(bypassing))。
在这里插入图片描述
下图是对转发技术的硬件支持。运算单元ALU计算产生的值e_valE、访存阶段从流水线寄存器M中读出的值M_valE和从内存中读出的值m_valM、写回阶段将要写入寄存器文件中的的值W_valE和信号W_valM,五个不同的转发源,两个不同的转发目的(valAvalB)。
在这里插入图片描述

5.5.2 控制冒险解决办法

当处理器无法根据处于取指阶段的当前指令来确定下一条指令的地址时,就会出现控制冒险,控制冒险只会发生在 ret 指令和跳转指令预测错误时

  • ret指令是将PC的设置为当前栈顶存放的值,所以只有ret指令经过了取指、译码、访存后,下一条指令才可以确定取指用的PC,这个冒险的解决方法也就只有暂停了。

  • 没有分支预测的硬件单元,跳转指令的控制冒险可以用暂停或者更高效的延迟槽技术(MIPS架构)。有分支预测,流水线会预测选择分支,即PC为预测的分支地址,若预测正确则一直执行,预测错误,流水线在错误执行的指令中插入气泡,同时取出正确地址处的指令。下图为处理器处理器应对预测错误时的方法:
    在这里插入图片描述在这里插入图片描述

5.6 异常处理

5.7 PIPE各阶段的实现

5.8 流水线控制逻辑

这三节,有空了看看书,了解一下就ok。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yelvens

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值