CA5 流水线技术(1)
CA5 流水线技术 (1)
指令执行过程
每条指令均可在5个时钟周期内完成。
ALU操作:IF 取指——ID 译码——Reg Fetch 读寄存器——ALU 执行——写结果回寄存器
MEM操作:IF 取指——ID 译码——Reg Fetch 读寄存器——计算有效地址——访存——(写回寄存器)
控制操作:IF 取指——ID 译码——Reg Fetch 读寄存器——计算有效地址(调转到的那个地址)——分支完成(将计算的地址存入 PC 寄存器)
将 ID 译码可以和 RF 读寄存器合并为一个时钟周期。
取指令IF
- 取指令
- 向存储器发出 PC 的内容
- 从存储器重取回当前指令
- 通过+4更新 PC 内容指向顺序的下一条指令(如果跳转了的话,+4的操作会被废弃掉)
- 优化
- 指令缓冲器(指令 Cache)
- 指令预取(一次不止读取一条指令,而包含了 PC 对应指令后边若干条指令,需要扩展指令寄存器 IR 的空间)
- 性能影响
- 代码密度
- 可变的指令长度
指令译码和读寄存器 ID
指令译码和取寄存器
- 指令译码
- 读源寄存器;为分支转移指令完成”相等“比较
- 偏移量符号扩展;为分支转移指令完成目标地址计算
指令译码和读寄存器同时进行
- 固定域译码:在 RISC 架构中寄存器标识符在指令中的固定位置
性能影响
- 指令格式的规律性
- 指令长度
分支指令目标地址计算的两种选择
- 指令译码阶段
- 指令执行阶段
执行与有效地址 EX
- 执行与有效地址
- 存储器访问:ALU将基址地址和偏移量相加形成有效地址
- reg-reg:ALU对从寄存器文件中读出的数值完成由ALU操作码指定的操作
- reg-立即数:ALU对从寄存器文件中读出的第一个操作数经过符号扩展的立即数完成ALU操作麻指定的操作
- 条件分支:判断条件是否为真
- 二者能够在单个时钟周期完成,是因为没有指令在计算某个数据地址的时候同时进行其它操作
- 上面的操作所需的所有内容均在 ID 段获得
存储器访问
- MEM access
- 存储器访问:获得有效地址,完成Load和Store
- 分支/跳转:使用计算得到的有效地址位 PC。
- 对于所有操作,有效地址
写回 WB
- 写回
- 只对reg-reg ALU指令和Load指令有效
- 将操作结果 ALU 指令或读入的数据 LOAD 指令写回到目标寄存器中
RISC 架构的非流水实现
每个阶段都在一个时钟周期内完成
每条指令执行最多需要5个时钟周期
- 分支转移指令:3 cycles
- STORE 指令:4 cycles
- 其它指令:5 cycles
该实现无论从最佳性能上还是从最小硬件数量上都不是最优的
- 容易理解
指令格式
- 所有指令采用 32 位编码,其中操作码为 6 位
- 只有两种寻址方式,三种指令类型:I、R、J
- 缩写
- opcode 6bit 操作麻
- rs 源寄存器
- rt 目标寄存器或分支条件寄存器说明符
- immediate 16位立即数,分支转移位移或地址位移
- target 26bit 跳转目标地址
- rd 5bit 源/目的寄存器说明符
- shamt 5bit 偏移量
- funct 6bit 功能域
I 型
6bit opcode | 5bit rs | 5bit rd | 16bit immediate
- 指令
- load store
- 所有带立即数的指令
- 寄存器跳转指令、寄存器跳转和链接指令
- 条件分支指令
- 注意事项
- 5bit 编码源和目标寄存器:最多32个reg
- 16bit 编码立即数
R 型
6bit opcode | 5bit rs | 5bit rt | 5bit rd | 5bit shamt | 6bit funct
- 指令
- reg-reg 操作
J 型
6bit opcode | 26bit offset
- 指令
- 跳转、跳转和链接
- 陷阱,从意外返回
ALU 数据通路
多路选择器Mux
LOAD 和 STORE 指令数据通道(哈弗结构)
什么是流水线
流水线 pipeline 是用来制造快速处理器的关键实现技术
利用连续指令中指令间存在的并行性,使得多条指令重叠执行。
类似于装配线 assembly line
- 包含许多同时进行的步骤(作用对象不同)
- 每个步骤都对最终产品做出一些贡献
流水段 pipe segment 流水线的组成部件
- 首尾相连,行成管道
- 指令从一端进入,经过所有流水段,从另一端离开
吞吐量:单位时间内离开流水线的指令数目
处理器周期:指令通过一个流水段的时间
- 由流水线中最慢的流水段的处理时间决定
- 定义为一个时钟周期
设计目标
- 平衡每个流水段的长度(所耗费的长度)
- 理想情形:每条指令执行时间、加速比等于流水段段数
- 流水线减少了每条指令的平均执行时间
- 如果每条指令需要多个时钟周期,则流水线减少了每条指令执行周期数 CPI
- 指令流水线对程序员是透明的
RISC 架构的流水实现
- 主要原则
- 所有数据操作都在寄存器进行
- 影响存储操作只有load和store
- 较少的指令格式
- 固定长度的指令编码
- 指令流水线在RISC架构上实现得更加简单
经典 RISC 五段流水线
- 构造指令五段流水线
- 流水操作
- 加速比:1~5
寄存器会出现在同一个时钟周期同时读写的问题,因此把访问寄存器的时钟周期分成两半,先写后读。
三点总结
- 将存储器分成指令存储器和数据存储器两部分
- 分别由指令缓存器和数据缓存器具体实现
- 存储带宽必须是原来带宽的五倍——高性能的代价
- 两个流水段访问寄存器文件 ID 段读,WB 段写
- 寄存器文件必须同时支持两个读操作和一个写操作
- 前半周期写,后半周期读(交换顺序导致效率降低)
- 处理 PC
- IF 段把每个时钟周期完成 PC + 4
- ID 段添加一个加法器计算可能的分支转移地址
- 在 ALU 段配置两个寄存器内容比较功能的 ALU
流水线寄存器
在时钟周期尾部存储流水段的所有结果,用于下个时钟周期下个流水段的输入
每个流水段后面都需要缓存
流水线危害
- 阻止指令流中下一条指令在其指定的时钟周期内执行的情况,降低了流水线性能。
- 导致流水线操作”停顿“
- 某条指令操作被停止期间
- 该指令的后续指令也将停顿
- 先于该指令发出的指令继续执行
流水线危害类型
- 结构危害 structural hazards:不能同时支持所有可能的指令组合:资源冲突
- 使用频度较低的特殊目的功能单元,如浮点数除法器等
- 程序员/编译器意识到指令低吞吐率时,将不予关注
- 数据危害 data hazards:一条指令依赖于流水线中重叠执行的早期指令的运算结果
- 控制危害 control hazards:分支转移指令和其它改变 PC 取值指令的流水操作
危害下的流水线性功能
流水线危害导致流水线性能退化
数据危害
- 指令重叠执行改变了指令间相对定时关系,导致了数据危害和控制危害
- 读/写顺序
- 写后读 RAW
- 读后写 WAR
- 简单五段指令流水线不可能发生
- 可能在重排序指令时发生
- 写后写 WAW
- 简单五段指令流水线不可能发生
- 可能在重排序指令或执行时间变化时发生
向前通道
向前:旁路 和 短路
将结果直接从流水线寄存器移动到需要的地方
流水线互锁
- 用途:围城正确执行模式的硬件
- 检测危害且停顿流水线操作直到危害被接触, 引入流水线停顿或气泡
控制危害
- 控制危害比数据危害带来更大的性能损失
- 分支转移危害
- 可能发生转移,也可能不发生转移
- 如果发生转移,那么 PC 将在 ID 段尾部(完成地址计算和比较)改变
- 最简单的解决办法
- 重新取入分支转移指令后的指令或转移目标地址的指令
- 每条分支转移指令停顿 1 个周期,将导致 10%~30%的性能损失
减少流水线分支转移惩罚
冻结流水线
- 保持或删除分支转移指令后的指令,直到获得目标地址位置
- 对于硬件和软件均是最简单的实现方法,分支惩罚是固定的
预测不发生转移
- 如果发生转移,则将已取入指令变为空操作指令,重新从目标地址取入指令
预测发生转移
- 只要译码为分支指令且获得目标地址。则假设发生转移而取指和执行
- 如果预测正确,则获得一个时钟周期的奖励。
无论预测转移还是不转移,编译器都可以通过组织代码使最频繁的路径与硬件选择匹配来提高性能。
延迟分支转移
分支延迟槽
无论分支指令是否发生转移,处于分支延迟槽中的指令一定执行
编译程序的工作是使得后继指令有效和有用
当动态分支预测技术出现之后,由于过于复杂,静态调度技术在 RISC V 中被淘汰
静态分支转移预测
- 关键:利用早期运行时搜集的信息
- 某条分支指令高度偏向于转移/不转移
分支预测缓存或分支历史表
分支历史表
2 比特预测法:预测改变前必须经历两次错误
实现:在 IF 段期间,使用指令地址访问小型、特定 Cache