课程
CH03
第三章:流水线技术
流水线相关概念、分类
- 部件级、处理机级及处理机间流水线
- 单功能流水线与多功能流水线
- 静态流水线与动态流水线
- 线性流水线与非线性流水线
- 顺序流水线与乱序流水线
掌握并应用流水线的性能指标
- 各段时间均等与不均等的计算;
- 吞吐率、加速比、效率
- 静态与动态流水线分析举例
流水线的相关
- 经典流水线的5个阶段及其作用
- 相关的三种类型:数据相关、名相关、控制相关
流水线冲突
- 三种:结构冲突、数据冲突、控制冲突——基本概念
- 三种数据冲突:RAW、WAR、WAW
- 控制冲突的三种软件解决方法:减少分支延迟、预测分支失败/成功、延迟槽技术
流水线概念和分类
流水线技术:
- 把一个重复的过程分解为若干个子过程,每个子过程由专门的功能部件来实现。
- 把多个处理过程在时间上错开,依次通过各功能段,这样,每个子过程就可以与其它的子过程并行进行。
流水线中的每个子过程及其功能部件称为流水线的级或段,段与段相互连接形成流水线。流水线的段数称为流水线的深度。
流水技术的特点:
- 流水线把一个处理过程分解为若干个子过程(段),每个子过程由一个专门的功能部件来实现。
- 流水线中各段的时间应尽可能相等,否则将引起流水线堵塞、断流。
时间最长的段将成为流水线的瓶颈。
- 流水线每一个段的后面都要有一个缓冲寄存器(锁存器),称为流水寄存器。
作用:在相邻的两段之间传送数据,以保证提供后面要用到的信息,并把各段的处理工作相互隔离。(先完成的部件暂存结果数据而不必要等待下一个段的工作再继续自己当前的工作)
- 通过时间:第一个任务从进入流水线到流出结果所需的时间。
- 排空时间:最后一个任务从进入流水线到流出结果所需的时间。
流水线的分类:
- 部件级、处理机级及处理机间流水线
- 单功能流水线与多功能流水线
- 静态流水线与动态流水线
- 线性流水线与非线性流水线
- 顺序流水线与乱序流水线
- 标量处理机与向量流水处理机
流水线的性能指标
吞吐率、加速比、效率
吞吐率
在单位时间内流水线所完成的任务数量或输出结果的数量
n:任务数 Tk:处理完成n个任务所用的时间
在各段时间均相等的流水线中,设单位时间∆t,段数为k,完成n个任务需要的时间Tk

流水线的实际吞吐率: 最大吞吐率:
即有 ,只有当n>>k时,才有TP≈TPmax
在各段时间不完全相等的流水线中
最大吞吐率
例如:一条4段的流水线中,S1,S3,S4各段的时间:ΔtS2的时间:3Δt (瓶颈段),最大吞吐率为:

加速比
完成同样一批任务,不使用流水线所用的时间与使用流水线所用的时间之比
假设:不使用流水线(顺序执行)所用的时间为Ts,使用流水线后所用的时间为Tk,则该流水线的加速比
在各段时间均相等的流水线中,流水线的实际加速比
最大加速比
效率
流水线中的理论运行时间与实际运行时间的比值,即流水线设备的利用率,即时空图上n个任务占用的时空面积和
k个段总的时空面积之比
在各段时间均相等的流水线中,整条流水线的效率
nΔt: n个任务,每个段被使用n次,共使用时间为nΔt
最高效率
在各段时间不完全相等的流水线中,先求出每个段的效率,然后求所有段的效率和

性能指标间的关系
当流水线各段时间相等时,流水线的效率E与吞吐率TP成正比,是流水线的实际加速比S与它的最大加速比k的比值



经典5段流水线
- 取指令周期 IF (Instruction Fetch)
以程序计数器PC中的内容作为地址,从存储器中取出指令并放入指令寄存器IR;
同时PC值加4(假设每条指令占4个字节),指向顺序的下一条指令。
- 指令译码/读寄存器周期 ID (Instruction Decode)
对指令进行译码,并用IR中的寄存器地址去访问通用寄存器组,读出所需的操作数。
- 执行/有效地址计算周期 EX (Execute)
寄存器-立即数ALU指令:ALU按照操作码指定的操作对从通用寄存器组中读出的操作数和指令中给出的立即数进行运算。
分支指令:ALU把指令中给出的偏移量与PC值相加,形成转移目标的地址。同时,对在前一个周期读出的操作数进行判断,确定分支是否成功。
- 存储器访问/分支完成周期 MEM (Memory Access)
该周期处理的指令只有load、store和分支指令。
- load和store指令
load指令:用上一个周期计算出的有效地址从存储器中读出相应的数据;
store指令:把指定的数据写入这个有效地址所指出的存储器单元。
- 分支指令
分支“成功”,就把转移目标地址送入PC。
分支指令执行完成。
- 写回周期 WB (Write Back)
ALU运算指令和load指令在这个周期把结果数据写入通用寄存器组

PC:程序计数器,存放当前指令的地址。
NPC:下一条程序计数器,存放下一条指令的地址。
IR:指令寄存器,存放当前正在处理的指令。
A:第一操作数寄存器,存放从通用寄存器组读出来的操作数。
B:第二操作数寄存器,存放从通用寄存器组读出来的另一个操作数。
Imm:存放符号扩展后的立即数操作数。
Cond:存放条件判定的结果。为“真”表示分支成功。
ALUo:存放ALU的运算结果。
LMD:存放load指令从存储器读出的数据。
请认真观察流水实现的数据通路图。完成以下内容:
请按照经典5段流水线的工作原理解析下面三条指令在上图数据通路中的实现。
- ADD R1,R2,R3
- load F6, 0(R6)
- IF (a>100) { } //只分析IF分支指令
1、ADD R1,R2,R3
IF段,将ADD指令取出放入IR寄存器。
ID段译码,将将源操作数R2,R3送入运算器的两端;
EX段,R1+R2,经ALU输出。
MEM段,无用;
WB 段通过ALUo输出写回通用寄存器R1。
2、 load F6, 0(R6)
IF段,将load指令取出放入IR寄存器。
ID段译码,将立即数符号扩展后送入ALU的一段, R6通过A口送入运算器的另一端,源操作数就绪;
EX段,立即数与R6内容相加,经ALU输出。MEM段,通过ALUo作为访存地址寻址到该单元;WB 段将寻址到的内容单元的内容写回通用寄存器F6。
3、IF (a>100) { } //只分析IF分支指令
IF段,将A分支指令取出放入IR寄存器。
ID段译码,将源操作数a和符号扩展后的立即数送往运算器的两端;
EX段,执行a-100,若条件成立,则修改cound=1;
MEM段完成分支目标地址返回IF段多路选择器,从而确定NPC的值;若分支失败,则cound=0,在多路选择器选择PC+4;
WB段,无用;
流水线相关
相关:两条指令之间存在某种依赖关系,如果两条指令相关,则它们就有可能不能在流水线中重叠执行或者只能部分重叠执行。
相关有3种类型
数据相关(也称真数据相关)
- 对于两条指令i(在前,下同)和j(在后,下同),如果下述条件之一成立,则称指令j与指令i数据相关。
指令j使用指令i产生的结果;
指令j与指令k数据相关,而指令k又与指令i数据相关。(数据相关具有传递性)
- 数据相关反映了数据的流动关系,即如何从其产生者流动到其消费者。
- 例:下面这一段代码存在数据相关。

名相关(反相关、输出相关)
- 名:指令所访问的寄存器或存储器单元的名称。
- 如果两条指令使用相同的名,但是它们之间并没有数据流动,则称这两条指令存在名相关。
- 指令j与指令i之间的名相关有两种(j后进入):
反相关:指令j写的名=指令i读的名
输出相关:指令j写的名=指令i写的名
- 名相关的两条指令之间并没有数据的传送。如果一条指令中的名改变了,并不影响另外一条指令的执行,所以可以用换名技术消除名相关,改变指令中操作数的名,对于寄存器操作数进行换名称为寄存器换名

控制相关
- 控制相关是指由分支指令引起的相关。
为了保证程序应有的执行顺序,必须严格按控制相关确定的顺序执行。
- 典型的程序结构是“if-then”结构。
if p1 和 if p2 编译成目标代码以后都是分支指令。语句S1与p1控制相关,S2与p2控制相关,S与p1和p2均无关。

- 与一条分支指令控制相关的指令不能被移到该分支之前。否则这些指令就不受该分支控制了。
对于上述的例子,then 部分中的指令不能移到if语句之前。
- 如果一条指令与某分支指令不存在控制相关,就不能把该指令移到该分支中。
对于上述的例子,不能把S移到if语句的then 部分中。
流水线冲突
流水线冲突是指对于具体的流水线来说,由于相关的存在,使得指令流中的下一条指令不能在指定的时钟周期执行。
流水线冲突有3种类型:
- 结构冲突:因硬件资源满足不了指令重叠执行的要求而发生的冲突。
- 数据冲突:当指令在流水线中重叠执行时,因需要用到前面指令的执行结果而发生的冲突。
- 控制冲突:流水线遇到分支指令和其它会改变PC值的指令所引起的冲突。
避免冲突:停顿一些指令的执行,当一条指令被暂停时,在该暂停指令之后流出的所有指令都=被暂停,而在该暂停指令之前流出的指令则继续进行(否则就永远无法消除冲突)
结构冲突
在流水线处理机中,为了能够使各种组合的指令都能顺利地重叠执行,需要对功能部件进行流水或重复设置资源。
如果某种指令组合因为资源冲突而不能正常执行,则称该处理机有结构冲突。
常见的导致结构冲突的原因:
- 功能部件不是完全流水
- 资源份数不够
举例:访存冲突
有些流水线处理机只有一个存储器,将数据和指令放在一起,访存指令会导致访存冲突
- 解决办法Ⅰ:(停顿指令)
插入暂停周期(“流水线气泡”或“气泡”),引入暂停后的时空图
为消除结构冲突引入的停顿将推迟流水线的完成时间,从而影响流水线的性能
- 解决方法Ⅱ: (增加硬件资源)
设置相互独立的指令存储器和数据存储器或设置相互独立的指令Cache和数据Cache。
会增加了硬件损失



数据冲突
当相关的指令靠得足够近时,它们在流水线中的重叠执行或者重新排序会改变指令读/写操作数的顺序,使之不同于它们串行执行时的顺序,则发生了数据冲突。


根据指令读访问和写访问的顺序,可以将数据冲突分为3种类型。(两条指令i和j ,且i在j之前进入流水线)
写后读冲突(RAW)(i写、j读) 数据真相关
- 后指令需要读取前指令尚未写完的值

DDIV在流水线中可能尝试读取 R1 的值,
但DADD 尚未完成对 R1 的写入。
读后写冲突(WAR)(I读、j写)
- 后指令修改了前指令尚未读出的值
- 这种冲突仅发生在这样的情况下:
有些指令的写结果操作提前了,而且有些指令的读操作滞后了
指令被重新排序了
写后写冲突(WAW)(i写、j写)
- 两条指令试图写入同一个寄存器,后一条指令的结果被前一条指令的结果覆盖。 这种冲突对应于输出相关。
- 写后写冲突仅发生在这样的流水线中:
流水线中不只一个段可以进行写操作;
指令被重新排序了。(乱序的流水线)
- 前面介绍的5段流水线不会发生写后写冲突。(只在WB段写寄存器)
控制冲突的三种软件解决方法
控制冲突:控制流改变(分支指令)造成的延迟
把由分支指令引起的延迟称为分支延迟
三种通过软件(编译器)来减少分支延迟的方法:减少分支延迟、预测分支成功/失败、延迟槽
- 对分支的处理方法在程序的执行过程中始终是不变的,是静态的(编译时完成的)。
- 要么总是预测分支成功,要么总是预测分支失败。
减少分支延迟
- 分支指令的条件测试和分支目标地址计算是在EX段完成,对PC的修改是在MEM段完成。它所带来的分支延迟是3个时钟周期。
- 把上述工作提前到ID段进行
在ID段增设一个加法器:计算分支目标地址
把条件测试“=0?”的逻辑电路移到ID段
这些结果直接回送到IF段的MUX1
改进后的流水线对分支指令的处理:

预测分支有两种结果
-
预测分支失败
允许分支指令后的指令继续在流水线中流动,就好象什么都没发生似的;
若确定分支失败,将分支指令看作是一条普通指令,流水线正常流动;
-
预测分支成功
当流水线检测到分支指令后,一旦计算出了分支目标地址,就开始从该目标地址取指令执行。
注意:这和预测分支失败不是一种方法;
延迟槽
分支延迟槽是指分支指令后面紧跟的一个或多个指令,在分支条件计算结果未确定时,处理器仍然会执行这些指令。编译器通过将无关紧要的指令插入到分支指令后面,使得这些指令可以在等待分支判断结果时执行,从而减少等待时间。













