流水线
流水线的基本概念
流水线的概念和术语
- 流水线的级/段:子功能及其部件
- 深度:有几段
- 流水寄存器:每段后的缓冲寄存器(锁存器),松耦合,数据缓冲
- 瓶颈:时间最长的段
流水线的分类
按规模分:
- 部件级流水线(运算操作流水线)
- 处理机级流水线(指令流水线)
- 系统级流水线(宏流水线)
按功能分:
- 单功能流水线:流水线只能完成一种功能
- 多功能流水线:各段可以进行不同的连接,流水线实现不同的功能
- 静态多功能流水线:同一时间内,各段通过某种连接方式实现一种功能,则空闲的段不能实现其他功能;功能切换时,所有段一起切换
- 动态多功能流水线:同一时间内,各段可以按照不同方式连接,实现不同功能;只要实现某一功能所需要的段都空闲,就可以切换开始执行这一功能
按流入和流出的顺序是否相同分:
- 顺序流水线:
- 流入和流出顺序相同
- 流水线内部各段的执行顺序也都相同
- 乱序流水线(无序、错序、异步流水线):
- 流入与流出可以不同
- 常见的情况是,内部各段乱序,进出有序
流水线的时空图描述方法
处理器的流水线——5段RISC流水线

- IF: Instruction Fetch
- ID: Instruction Decode
- EX: EXcute
- MEM: MEMory
- WB: Write-Back

IF:取指令周期

- 根据PC,从存储器取指令
- PC + "1"(若假设每条指令占四个字节,则PC + 4)
- 向流水寄存器(IF/ID)中写状态信息
ID:指令译码、读寄存器周期

- 译码,建立控制信号
- 读寄存器(图中两个源寄存器
regA和regB) - 向流水寄存器(ID/EX)写状态信息
EX:执行/有效地址计算周期

- 对于
LOAD和STORE指令,要计算访存有效地址(MIPS指令集中只有LOAD和STORE指令可以访问内存) - 对于其它ALU指令,执行运算
- 分支指令:计算转移目标地址(即图中PC + 1 + 偏移量)
图中MUX代表选择器,因为ALU操作也可能是立即数操作,直接从控制信号中获取参与运算的源操作数
MEM:存储器访问/分支完成周期

- 只有
LOAD、STORE和分支指令涉及此周期,其它类型的指令在此周期不做任何操作 LOAD、STORE:完成存储器读写- 分支指令:分支成功,将上一周期有效地址计算结果写入PC;分支失败则不进行操作
WB:写回周期

- 将数据写回通用寄存器组:对于
LOAD指令,数据来源于存储器,对于ALU运算,数据来源于ALU,即图中MUX选择器的作用 - 图中
data和destReg送回到ID周期图中的Register File中
流水线的性能指标
吞吐率
单位时间内完成任务数
: 任务数
: 总时间
各段时间均相等的情况

吞吐率:
各段时间不完全相等的情况

由于各段时间不完全相等,故存在瓶颈段,解决方法:
- 细分瓶颈段:拆分子段
- 重复设置瓶颈段:设置多个瓶颈段,达到平行
加速比
效率
流水线中的设备实际使用时间与整个运行时间的比值,即流水线设备的利用率
从时空图中计算:
类似于阴影部分面积占矩形总面积的百分比
流水线的性能分析举例
例1
例2
流水线的相关与冲突
MIPS指令集介绍
待补充
相关
描述两条指令之间的关系。若两条指令之间存在某种依赖关系(某条指令只能在某条指令之前或之后),则称两条指令相关。分为:
- 数据相关(真相关)
- 名相关
- 控制相关
数据相关(真相关)
对于两条数据相关指令和
(
在前,
在后),满足以下二者之一:
使用
的结果
与
真相关,
与
真相关(传递性)
数据相关无法消除(反应了数据的流动)
名相关
分为两种情况:
- 反相关:读后写
- 输出相关:写后写
名相关可以消除:换名技术,可以用编译器静态实现,也可以用硬件动态完成
控制相关
由分支指令引起的相关,保证程序应有的执行顺序。有以下两个限制:
- 分支内的指令不能移到分支之前
- 分支外的指令不能移到分支之内
冲突
流水线冲突:对于具体流水线,由于某些原因(流水线硬件资源、相关的存在),指令流中的下一条指令不能在指定的时钟周期执行
三种类型:
- 结构冲突
- 数据冲突
- 控制冲突
结构冲突
硬件资源满足不了指令重叠进行
如经典五段流水线中IF和MEM周期中都需要访问存储器:

- 插入气泡
- 将指令存储和数据存储独立(哈佛架构)
数据冲突
相关的指令顺序改变,发生数据冲突
相关的几种情况都会引起数据冲突,分别对应:
- RAW冲突:真相关
- WAR冲突:名相关-反相关
- WAW冲突:名相关-输出相关
数据冲突的硬件解决方法:定向技术(旁路技术、旁路直通)
并不是所有数据冲突都可以通过定向技术解决,有些需要插入气泡,或通过指令调度等解决
控制冲突
分支指令或其它会改变PC值的指令引起的冲突
流水线优化和指令调度
流水线冲突的解决途径:
- 硬件方法
- 硬件组成与实现:旁路直通、插入气泡、哈佛结构
- 硬件系统结构的优化:指令动态调度
- 软件方法:编译器静态优化
编译器方面的流水线优化
基本程序块
所谓基本块,是指程序—顺序执行的语句序列,其中只有一个入口和一个出口,入口就是其中的第—个语句,出口就是其中的最后一个语句。对一个基本块来说,执行时只从其入口进入,从其出口退出。
循环级并行
使循环中不同循环体并行执行。主要有以下两种方法:
- 循环展开
- 采用向量指令和向量数据表示
循环展开
- 保证正确性
- 使用不同寄存器,消除名相关(WAW、WAR)
- 删除多余的测试指令和分支指令
静态的分支预测与处理
编译器层面通常采用三种方法:
- 预测分支失败
- 预测分支成功
- 延迟分支
预测分支失败
- 无论什么情况都预测分支失败。
- 编译器进行编译时,继续取下一条指令。
- 要保证分支结果出来之前不能改变处理机的状态,即预测失败时能退回到原先的状态
预测分支成功
- 需要先知道分支目标地址
- 流水线中仍然会有气泡周期(需要知道分支地址)
延迟分支
在分支指令之后设置延迟槽,放入不受分支指令影响的指令。
三种调度方法:
- 从前调度
- 从目标处调度
- 从失败处调度
指令的硬件动态调度
主要考量:RAW、WAR、WAW、结构冲突
记分牌算法
基本思想:译码ID段需要做两件事情:译码、读寄存器,二者不相关,故可以将这一阶段拆分成两段,即:
- 流出(Issue,IS):指令译码、检查是否存在结构冲突
- 读操作数(Read Operands,RO):无数据冲突后,读操作数
流出阶段
- 可以流出的条件:
- 流出指令所需的功能部件空闲:不存在结构冲突
- 所有其他正在执行的指令的目的寄存器与该指令不同:无写后写冲突
- 记分牌向功能部件流出该指令,修改记分牌内部记录表 流出阶段保证了不会出现结构冲突和WAW冲突:通过阻止指令流出来实现
读操作数阶段:
- 记分牌检测源操作数是否可用:不可用意味着需要等待其它指令写入,可用即不存在写后读冲突
- 当数据可用时,通过之功能部件,从寄存器中读出源操作数并执行
执行阶段
- 取到操作数后,功能部件开始执行
- 产生结果后通知记分牌
写结果阶段
- 不存在读后写冲突时才可以写入:没有反相关的指令依赖
- 写入:记分牌通知功能部件把结果写入目的寄存器,并释放指令使用的所有资源
总结:冲突的消除
- RAW:RO阶段
- WAR:WB阶段
- WAW:IS阶段
- 结构冲突:IS阶段
实际上并没有采取行动去消除冲突,而是在特定的阶段等待某些冲突的消失。即记分牌算法保证了没有冲突,采用了一种容忍和等待的策略,但没有从根本上消除冲突。故其对于性能的提升有限。
托马苏格算法
待补充