4.14 数据转发
基本思想
数据转发(Data Forwarding,也称 Bypassing)的核心思想是:当一条指令的计算结果已经产生但尚未写回寄存器时,将这个结果通过旁路路径直接传递给需要它的指令,不必等待写回寄存器文件。
转发的硬件实现
转发需要在译码阶段增加多路选择器,从多个可能的数据源中选择正确的值:
译码阶段读寄存器值 valA/valB
↓
[mux] ← 选择信号来自转发控制逻辑
├─ 0:普通寄存器文件输出
├─ 1:执行阶段的结果 valE(转发)
├─ 2:访存阶段的结果 valE/valM(转发)
└─ 3:写回阶段的结果(即将写入寄存器)
↓
转发后值进入执行阶段
可以转发哪些结果
| 结果来源 | 可用时间 | 转发目标 |
|---|---|---|
| ALU 计算结果(valE) | 执行阶段后 | 下一条指令的 ALU 输入 |
| 内存读取结果(valM) | 访存阶段后 | 下一条指令的 ALU 输入 |
| 写回阶段的数据 | 写回阶段 | 译码阶段的输入 |
转发控制逻辑
转发控制逻辑需要检测以下条件:
# 执行阶段的转发条件
if (E_dstE != 0xF) && (E_dstE == d_srcA) then 转发 valE 到 valA
if (E_dstE != 0xF) && (E_dstE == d_srcB) then 转发 valE 到 valB
# 访存阶段的转发条件
if (M_dstE != 0xF) && (M_dstE == d_srcA) then 转发 valE 到 valA
if (M_dstE != 0xF) && (M_dstE == d_srcB) then 转发 valE 到 valB
其中 E_dstE 是执行阶段寄存器中保存的目标寄存器编号,d_srcA 是当前译码指令的源寄存器编号。如果相等且不为 0xF(无寄存器),说明发生了 RAW 相关,需要转发。
转发解决大多数RAW冒险
转发可以解决除加载使用冒险外的所有 RAW 冒险。加载使用冒险的特殊之处在于:加载指令的结果直到访存阶段末尾才可用,而需要该结果的指令在译码阶段就需要——时间上来不及。
转发的优点
- 不需要暂停流水线,不增加 CPI
- 硬件开销相对较小(多路选择器 + 比较器)
- 是流水线设计中的标配技术
相关笔记
链接到
- 上一个知识点:4.13 暂停机制
- 下一个知识点:4.15 加载使用冒险