4.13 暂停机制
基本概念
暂停(Stall)是解决流水线冒险的一种保守策略——当检测到数据冒险时,让流水线的一部分暂停,等待冒险消除后再继续。暂停具体表现为在流水线中插入”气泡”(Bubble),即空操作。
暂停的实现方式
暂停通过冻结流水线寄存器来实现:
- 流水线寄存器的使能信号(enable) 被置为无效
- 寄存器保持当前值不变
- 时钟上升沿不会将新数据锁存进来
这实际上等价于让指令在某一阶段停留一个额外的周期。
插入气泡
插入气泡是指将流水线寄存器中的控制信号清零(或置为 nop 对应的编码),使后续阶段执行一个空操作。
气泡在流水线中的效果:
- 不改变寄存器值
- 不写内存
- 不更新条件码
- 仅仅占用一个时钟周期
暂停的适用场景
暂停主要用于以下情况:
- 加载使用冒险(Load-Use Hazard):加载指令的结果被紧随其后的指令使用,转发无法完全解决,需要暂停一个周期
- ret 指令:返回地址未知,需要暂停到访存阶段完成
- 预测错误的分支:需要清空已取指的指令
暂停的代价
暂停的直接代价是 CPI 增加。每个暂停周期意味着流水线没有完成任何有用工作,流水线的有效吞吐量降低。
暂停 vs 转发
| 特性 | 暂停 | 转发 |
|---|---|---|
| 策略 | 等待 | 旁路 |
| 代价 | CPI 增加 | 硬件复杂度增加 |
| 适用 | 转发无法解决的场景 | 大多数 RAW 冒险 |
| 实现 | 控制寄存器使能信号 | 多路选择器选择数据源 |
实际上,Y86-64 的流水线设计采用转发为主、暂停为辅的策略——大多数 RAW 冒险通过转发解决,只在加载使用冒险等少数场景下使用暂停。
相关笔记
链接到
- 上一个知识点:4.12 数据相关与冒险
- 下一个知识点:4.14 数据转发