4.13 暂停机制

基本概念

暂停(Stall)是解决流水线冒险的一种保守策略——当检测到数据冒险时,让流水线的一部分暂停,等待冒险消除后再继续。暂停具体表现为在流水线中插入”气泡”(Bubble),即空操作。

暂停的实现方式

暂停通过冻结流水线寄存器来实现:

  • 流水线寄存器的使能信号(enable) 被置为无效
  • 寄存器保持当前值不变
  • 时钟上升沿不会将新数据锁存进来

这实际上等价于让指令在某一阶段停留一个额外的周期。

插入气泡

插入气泡是指将流水线寄存器中的控制信号清零(或置为 nop 对应的编码),使后续阶段执行一个空操作。

气泡在流水线中的效果:

  • 不改变寄存器值
  • 不写内存
  • 不更新条件码
  • 仅仅占用一个时钟周期

暂停的适用场景

暂停主要用于以下情况:

  1. 加载使用冒险(Load-Use Hazard):加载指令的结果被紧随其后的指令使用,转发无法完全解决,需要暂停一个周期
  2. ret 指令:返回地址未知,需要暂停到访存阶段完成
  3. 预测错误的分支:需要清空已取指的指令

暂停的代价

暂停的直接代价是 CPI 增加。每个暂停周期意味着流水线没有完成任何有用工作,流水线的有效吞吐量降低。

暂停 vs 转发

特性暂停转发
策略等待旁路
代价CPI 增加硬件复杂度增加
适用转发无法解决的场景大多数 RAW 冒险
实现控制寄存器使能信号多路选择器选择数据源

实际上,Y86-64 的流水线设计采用转发为主、暂停为辅的策略——大多数 RAW 冒险通过转发解决,只在加载使用冒险等少数场景下使用暂停。

相关笔记

链接到