分支预测总览
分支预测器回答两个问题:这次取指块里哪里会跳?跳到哪里? 如果等分支执行后再回答,宽发射乱序核会长期没有指令可喂。
先建立组件地图
Predictor 是流水和恢复的组织者;Composer 实例化并连接各预测组件,收集它们的预测结果与训练元数据。FTB、TAGE-SC、ITTAGE、RAS 并不是四个互相竞争的完整答案,它们分别提供取指块结构、方向、间接目标与返回目标。
源码阅读顺序
frontend/BPU.scala:235:从class Predictor看请求、流水和 redirect。frontend/Composer.scala:23:看组件怎样并联、meta 怎样拼接与拆回。frontend/FTB.scala:465:理解一个取指块里分支槽位和目标的组织。frontend/Tage.scala:638、:1096:理解 TAGE 与统计修正器。frontend/ITTAGE.scala:409:理解间接跳转目标预测。frontend/newRAS.scala:96:理解推测栈、提交栈和错误恢复。frontend/NewFtq.scala:看预测结果怎样跨过前端并等待提交训练。
一次预测发生了什么
| 阶段 | 主要工作 | 你应观察什么 |
|---|---|---|
| s0 | 接收 PC、生成表索引 | 请求是否 fire,PC 是否被 redirect 替换 |
| s1 | 快速预测先给方向/目标线索 | fast predictor 是否命中 |
| s2 | 更多表项返回并修正 | FTB/TAGE 的命中与选择 |
| s3 | 形成最终预测和 meta | 最终 taken、target、history |
| update | 后端结果训练预测器 | 实际结果、旧 meta、写表选择 |
阅读技巧
先沿着 io.out.s1/s2/s3 读“预测路径”,再沿 io.update 读“训练路径”,最后读 redirect 的“恢复路径”。三条线混在一起读很容易迷路。
Composer 中最值得理解的一段
Composer 将每个组件的 last_stage_meta 拼成一个整体,训练时再按相反顺序拆回去。meta 不是预测结果本身,而是日后更新预测器所需的“当时现场”。这也是为什么 FTQ 必须把预测上下文保存到分支真正解析之后。
自测题
- 为什么 RAS 需要推测状态和提交状态,而不仅是一只普通栈?
- TAGE 只预测 taken/not-taken 时,跳转目标从哪里来?
- redirect 后,为什么只改 PC 还不够,还必须恢复全局历史?
meta_size为什么必须有总长度上限?
下一步进入逐拍追踪实验,把这些对象在波形中找出来。