首页/计算机组成原理/中央处理器/数据冒险处理 🔗 在 Obsidian 中打开
计算机组成原理 · 中央处理器

数据冒险处理

重要度 ⭐⭐⭐⭐⭐中央处理器流水线数据冒险数据冲突转发CPU
速查
数据冒险指后续指令需要前面指令的结果,但该结果尚未写回。三种类型:RAW(写后读)、WAR(读后写)、WAW(写后写);最常见是 RAW。最优解:转发/旁路(0 停顿)。

速查

项目
定义后续指令需要前面指令的结果但结果尚未写回
三种类型RAW(写后读)、WAR(读后写)、WAW(写后写)
最常见RAW(真数据相关)
解决方法转发 / 旁路、流水线停顿、编译器调度
转发将结果直接从流水段传给需要的指令,不停顿
停顿插入气泡等待数据就绪

核心概念

什么是数据冒险?

数据冒险是指后续指令需要用到前面指令的结果,但该结果尚未写回寄存器 / 存储器

三种数据冒险类型

类型名称含义五级流水线中是否出现
RAW写后读i 写 → j 读是(最常见)
WAR读后写i 读 → j 写否(顺序执行不会出现)
WAW写后写i 写 → j 写否(顺序执行不会出现)
注意WAR 和 WAW 只在乱序执行动态流水线中出现。

RAW 冒险示例

指令1: ADD R1, R2, R3   // R1 = R2 + R3,在 EX 阶段产生结果
指令2: SUB R4, R1, R5   // 需要 R1 的值,在 ID 阶段读 R1

指令2在 ID 读 R1 时,指令1的 R1 还在 EX 阶段(未写回) → RAW 冒险

数据冒险的检测条件

指令 j 在 ID 阶段读寄存器 X,且存在前面的指令 i 满足:

  • 指令 i 在 EX / MEM / WB 阶段写寄存器 X
  • 指令 i 和 j 之间距离太近(1~2 条指令)

解决方法

1. 转发 / 旁路(Forwarding / Bypassing)—— 最优解

不等写回,直接将结果从流水段寄存器传给需要的地方:

EX结果  → 转发到 → EX输入(EX-to-EX 转发)
MEM结果 → 转发到 → EX输入(MEM-to-EX 转发)
  • 不需要停顿,硬件实现;最常用的解决方案。

2. 流水线停顿(Stall)

插入气泡等待结果写回:简单但降低性能,通常配合编译器调度使用。

3. 编译器调度

// 调度前(需要停顿)
ADD R1, R2, R3
SUB R4, R1, R5  // 紧跟,RAW 冒险
// 调度后(无冒险)
ADD R1, R2, R3
OR  R6, R7, R8   // 插入无关指令
SUB R4, R1, R5   // 距离拉远,转发即可

4. 流水线互锁(Interlock)

硬件检测冒险并自动插入停顿。

关键性质

解决方法停顿周期优点缺点
转发 / 旁路0无性能损失增加硬件复杂度
停顿 1~2 周期1~2简单降低性能
编译器调度0不增加硬件依赖编译器
Load-Use 冒险必停 1 周期转发无法解决

Load-Use 冒险

LW  R1, 0(R2)   // 从存储器加载 R1,MEM 阶段才出结果
ADD R3, R1, R4   // 需要 R1,EX 阶段就要用

即使有转发,也必须停顿 1 个周期(MEM → EX 来不及) → Load-Use 冒险

常见考法

考法解题套路
识别数据冒险类型RAW:后指令读前指令写的寄存器
判断是否需要停顿能用转发解决 → 不停顿;Load-Use → 停 1 周期
画转发路径EX 结果转发到 EX 输入,MEM 结果转发到 EX 输入
编译器调度插入无关指令拉开距离
计算停顿周期数无转发:1~2 周期;有转发:Load-Use 1 周期

易错点

必记
  1. WAR 和 WAW 在顺序流水线中不会出现(只有乱序才有)。
  2. Load-Use 冒险即使有转发也必须停 1 个周期。
  3. 转发是从 EX / MEM 段的结果直接送到 EX 输入,不经过 WB。
  4. 不是所有 RAW 都需要停顿,很多可以通过转发解决。
  5. 分支指令后面紧跟使用分支结果的指令 → 控制冒险 + 数据冒险。

核心结论

  1. RAW 是最常见的数据冒险(写后读)。
  2. 转发 / 旁路是最优解决方法(不需停顿)。
  3. Load-Use 冒险必须停 1 个周期(无法完全用转发解决)。
  4. 编译器调度可以配合转发进一步减少停顿。
  5. WAR 和 WAW 只在乱序执行中出现。

记忆卡片

三种数据冒险类型?
RAW(写后读)、WAR(读后写)、WAW(写后写)。
顺序流水线中最常见的是?
RAW(真数据相关)。
什么是转发 / 旁路?
将 EX / MEM 阶段的结果直接传给后续指令的 EX 输入。
Load-Use 为什么必须停顿?
Load 在 MEM 才出结果,下一条 EX 就需要 → 转发来不及。
编译器如何帮助解决?
调度指令顺序,插入无关指令拉开相关指令距离。

交互动画 · RAW 冒险的转发与停顿

两条指令:i: ADD R1,R2,R3(写 R1)与 j: SUB R4,R1,R5(读 R1)。切换"转发 / 停顿"观察差异。

IFIDEXMEMWB i: ADD R1 EX 产生 R1 j: SUB R4,R1 EX 需要 R1 转发 停顿
橙色流动虚线表示转发路径:i 在 EX 段算出的 R1 直接送入 j 的 EX 输入,无需等 WB 写回。

★ 演示级:选择处理方式,逐拍推进 MIPS 五段流水线(IF/ID/EX/MEM/WB)周期表 —— i 写 R1,j 读 R1,形成 RAW 依赖。

拍 1拍 2拍 3拍 4 拍 5拍 6拍 7拍 8拍 9 i: ADD R1,R2,R3 j: SUB R4,R1,R5 EX→EX 转发 i 在 WB 写回 R1;j 在 ID 段需要 R1 —— 绿色单元格 = 写回/就绪,橙色描边 = 当前拍聚焦
IF 取指 ID 译码 EX 执行 MEM 访存 WB 写回 气泡(停顿)
1 / 6

相关知识点

structural-hazard-handling control-hazard-handling instruction-pipeline

↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。