冒险与停顿
- 结构冒险
- 每个部件每个周期只能被一条指令使用
- 数据冒险
- 前递(forwarding)或旁路: 上级已经计算出新值,下一级(以及之后)不必等待,直接拿到数据 e.g.
sub x2, x1, x3; and x12, x2, x5
,其中x2
在sub
指令的EX阶段算出来新值后可以立即前递给and
指令的EX阶段 - 停顿(stall)或气泡: 无法前递的冒险(比如载入-使用型数据冒险)只能停顿,检测到停顿后,让前面环节也停顿,同时将控制信号全部置无效,使后续环节执行空指令. e.g.
load x1; sub x4, x1, x5
,其中sub所需的x1
在MEM阶段才能拿到,所以只能停顿.
- 前递(forwarding)或旁路: 上级已经计算出新值,下一级(以及之后)不必等待,直接拿到数据 e.g.
- 控制冒险: 条件分支需要几个周期之后才能得出决定
- 提前判断条件分支
- 动态分支预测: 使用分支预测缓存:低地址定位的缓存,存储是否发生了跳转.
- 1位预测机制: 记录跳转情况,当预测失败后改变预测.
- 2位预测机制: 当两次预测失败后才改变预测.
- 相关预测器
- 锦标赛分支预测器
- 延迟决定: MIPS的延迟槽
指令间的并行性
- 增加流水线级数: 更长,更平衡
- 多发射
- 静态发射: 由编译器判断发射与否
- 代表处理器:
- 双发射: ALU和ld/sd两类指令成对发射
- 超长指令字处理器: 打包,正确性和软件调度有关(而超标量则无关)
- 编译优化:
- 循环展开: 便于统一调度更多指令
- 寄存器重命名: 消除名字相关(只是名字相关,而不是真的数据相关)
- 代表处理器:
- 动态发射: 由硬件判断
- 代表处理器:
- 超标量处理器
- 动态调度流水线: 按序发射,乱序执行(不阻塞后续无关指令的执行),按序提交
- 代表处理器:
- 静态发射: 由编译器判断发射与否
Cache
- 原理: 两个局部性
- 时间局部性
- 空间局部性
- 设计特点
- 功能
- I-Cache: 除非预测跳转, 延迟问题不大, 采用组相联
- D-Cache: 为了支持多条ld/sw指令, 需要多端口的设计, 从而导致较大的延迟和面积, 采用组相联
- TLB: 采用全相联
- Victim Cache: 采用全相联
- 级
- L1: 求快, 容量小, SRAM实现, 哈佛架构(即分为I-Cache和D-Cache两个),重点降低命中时间
- L2: 求全, 以MB为单位, 延迟不重要, 指令和数据共享, 需要比较高的命中率(否则会访问缓慢的DRAM),重点降低失效率
- L3: 多核共享
- 功能
- Cache缺失的"3C定理"
- Compulsory: 强制失效,第一次必定发生的缺失, 采用预取解决
- Capcity: 容量失效
- Conflict: 冲突失效,多个数据映射到同一位置的冲突, 采用组相联/Victim Cache解决
- 结构
- 全相联: 简单, 两个冲突交替访问造成严重缺失
- 组相联: 失效率更低, 但延迟更大(为了提高频率, 采用流水线解决, 但是又会造成访存指令的延迟)
- 串行访问: 先访问Tag, 根据结果再去访问Data. 流水线后, 频率更高, 但是访存多一个周期, 对于乱序友好, 对于顺序不好
- 并行访问: 读Tag的同时, Data的内容全部被读出, 一个多路选择器根据tag内容选出对应的data(称为数据对齐 Data Alignment). 流水线后, 访存周期较少, 但是频率较低, 对于顺序友好
- 全相联: 相当于内容寻址储存器, 延迟大, 容量一般不会大
- 写入
- 在
- Write Through: 写通、写穿透
- Write Back: 写回、写返回
- 不在
- Non-Write Allocate(写不分配): 直接写到下级存储器,并不取到cache中
- Write Allocate(写分配): 先从下级存储器取出地址所在的data block, 然后将要写入的数据合并, 再写到cache中, 然后如果写通,则还要写到下级存储器, 实现了存储器一致性; 如果写回,则标记懶标记.
- 在
- 失效率的关系
- 块的容量:越大空间局部性越好,但是失效损失更严重(从下一级存储获取并加载数据的时间),所以块容量大小要视存储带宽而定
- 分离cache会比同等容量的混合cache带宽更高(加倍),但失效率会更高
- 相联度越高,失效率越低,但命中时间更长
- 可靠性
- MTBF(平均失效时间)= MTTF(平均无故障时间)+ MTTR(平均修复时间)
- 可用性 = $\frac{MTTF}{MTTF+MTTR}$
分支预测
- 分支要素
- 方向: 跳不跳?
- 目标地址
- 直接跳转: 地址蕴含在指令中
- 间接跳转: 地址在寄存器, 惩罚更大
- 任务
- 确定哪些是分支指令:
- 方法一: 在写入I-Cache时同时预解码(pre-decode), 和数据一起写入I-Cache
- 方法二: 根据PC进行判断, 因为除了自修改和进程切换, PC和指令是一一对应的, 如果曾经分支过, 那么下一次碰见这个PC一定也会分支
- 方向预测
- 静态分支预测: 预测总是跳转或总是不跳转
- 动态分支预测
- last-outcome prediction: 每次根据上一次跳转情况预测
- 2-bit saturating counter: strongly和weekly预测
- 储存: PHT(Pattern History Table), PHT空间比PC空间小, 所以会造成别名(aliasing), 需要权衡PHT大小. PHT 2KB时, 准确度达到93%以上.
- 可以用PC的一部分来寻址
- 哈希
- 储存: PHT(Pattern History Table), PHT空间比PC空间小, 所以会造成别名(aliasing), 需要权衡PHT大小. PHT 2KB时, 准确度达到93%以上.
- 确定哪些是分支指令:
本文采用知识共享署名4.0国际许可协议(CC BY 4.0)进行许可