| 项目 | 值 |
|---|---|
| 定义 | 分支指令改变 PC 值,导致已取指令可能无效 |
| 别名 | 控制冲突、分支冒险 |
| 产生原因 | 分支结果在流水线后期才确定 |
| 最简单解法 | 插入 1~2 个停顿周期(冻结流水线) |
| 最优解法 | 分支预测 + 推测执行 |
| 分支代价 | 预测错误时需冲刷已执行的指令 |
控制冒险发生在分支指令(条件跳转 / 函数调用 / 返回)改变程序执行顺序时。
分支指令的目标地址和是否跳转通常在 EX 阶段或 MEM 阶段才确定,但流水线在 ID 阶段就已经取了后续指令。如果分支跳转了,已取的指令是错误的 → 需要冲刷(Flush)。
BEQ R1, R2, target // 分支指令
ADD ... // IF: 已取,但分支跳转 → 指令无效!
SUB ... // IF: 已取,同样无效
target: OR ...用分支历史表(BHT)记录分支的历史行为:
| 解决方法 | 代价 | 准确率 | 硬件复杂度 |
|---|---|---|---|
| 停顿 | 1~2 周期 | 100% | 无 |
| 预测不跳转 | 预测错时冲刷 | ~50% | 低 |
| 预测跳转 | 预测错时冲刷 | ~50% | 低 |
| 1 位动态预测 | 预测错时冲刷 | ~85% | 中 |
| 2 位动态预测 | 预测错时冲刷 | ~90% | 中 |
| 延迟分支 | 无 | — | 低(需编译器配合) |
| 考法 | 解题套路 |
|---|---|
| 识别控制冒险 | 分支 / 跳转指令后紧跟的指令 |
| 计算停顿周期 | 分支确定阶段 − IF 阶段 = 停顿周期数 |
| 2 位预测器状态转移 | 根据历史预测和实际结果更新状态 |
| 分支代价计算 | 预测错概率 $\times$ 冲刷周期数 |
| 延迟分支分析 | 延迟槽中的指令总是被执行 |
2 位饱和计数器:需连续两次错误才翻转预测。点击"实际跳转 / 不跳转"观察状态转移与当前预测方向。
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。