预测器的组合逻辑级联
代码实现
所有预测器的连接(config-mixins.scala:603-609):
1 2 3 4 5 6 7 8 9 10 11 12
| val resp_in = (0.U).asTypeOf(new BranchPredictionBankResponse)
ubtb.io.resp_in(0) := resp_in bim.io.resp_in(0) := ubtb.io.resp btb.io.resp_in(0) := bim.io.resp tage.io.resp_in(0) := btb.io.resp loop.io.resp_in(0) := tage.io.resp
final_resp = loop.io.resp
|
每个预测器的覆盖策略
| 预测器 |
覆盖字段 |
条件 |
| uBTB |
predicted_pc, is_br, is_jal, taken |
标签匹配 |
| BIM |
taken |
总是(基于PC) |
| BTB |
predicted_pc |
标签匹配且置信度高 |
| TAGE |
taken |
provider命中且置信度高 |
| Loop |
taken |
检测到循环边界且conf=7 |
组合逻辑路径
在F1阶段(最长路径):
1 2 3 4 5 6 7 8 9 10 11
| resp_in (0ns) → uBTB读SRAM (SRAM access) → uBTB标签比较 + Mux选择 (~0.5ns) → BIM读SRAM (SRAM access) → BIM计数器比较 + Mux选择 (~0.3ns) → BTB读SRAM (SRAM access) → BTB标签比较 + Mux选择 (~0.5ns) → TAGE读所有表 (parallel SRAM access) → TAGE找provider + 计算预测 (~1ns) → Loop表查找 + 边界检测 (~0.5ns) → final output (~总共3-4ns + SRAM延迟)
|
关键路径优化:
- SRAM访问在F0就开始(投机性)
- 某些预测器可以配置在不同阶段输出(如BIM的slow模式)
- 使用bypass逻辑减少RAW hazard
完整预测示例
假设我们要预测以下代码:
1 2 3 4 5 6
| int sum = 0; for (int i = 0; i < 100; i++) { if (i % 2 == 0) { sum += i; } }
|
第一次执行
分支A (PC=0x1000), i=0
| 阶段 |
预测器 |
动作 |
结果 |
| F1 |
uBTB |
Miss(首次) |
无预测 |
| F1 |
BIM |
读取,初始值=2(弱taken) |
Taken |
| F2 |
BTB |
Miss |
保持BIM结果 |
| F3 |
TAGE |
T0命中,ctr=4 |
Taken |
| F3 |
Loop |
Miss |
保持TAGE结果 |
| 最终 |
- |
- |
Taken ✓ |
分支B (PC=0x1004), i=0, i%2==0
| 阶段 |
预测器 |
动作 |
结果 |
| F1 |
uBTB |
Miss |
无预测 |
| F1 |
BIM |
初始值=2 |
Taken |
| F3 |
TAGE |
T1命中(hist=2bit) |
Taken |
| 最终 |
- |
- |
Taken ✓ |
第50次执行
分支A (PC=0x1000), i=49
| 阶段 |
预测器 |
动作 |
结果 |
| F1 |
uBTB |
命中,ctr=3(饱和) |
Taken |
| F1 |
BIM |
ctr=3 |
Taken |
| F3 |
TAGE |
T5命中(64bit hist),ctr=7 |
Taken |
| F3 |
Loop |
命中,s_cnt=49, p_cnt=100, conf=5 |
保持Taken |
| 最终 |
- |
- |
Taken ✓ |
第100次执行(循环边界)
分支A (PC=0x1000), i=99
| 阶段 |
预测器 |
动作 |
结果 |
| F1 |
uBTB |
命中,ctr=3 |
Taken |
| F1 |
BIM |
ctr=3 |
Taken |
| F3 |
TAGE |
T5命中,ctr=7(强taken) |
Taken |
| F3 |
Loop |
命中,s_cnt=99, p_cnt=100, conf=7 |
反转!Not Taken |
| 最终 |
- |
- |
Not Taken ✓ |
没有Loop预测器,TAGE会预测Taken → 错误 ✗
第101次执行(循环结束后)
下一条指令 (PC=0x1008)
分支A不再执行,成功退出循环。
总结
关键要点
4级流水 vs 5个预测器:
- 4级是时间维度(F0→F1→F2→F3)
- 5个预测器在每级内部通过组合逻辑级联
级联而非投票:
- 每个预测器可以选择保持或覆盖前级预测
- 后级预测器(TAGE)通常更准确
分工明确:
- uBTB: 快速但不准
- BIM: 简单基础预测
- BTB: 准确目标地址
- TAGE: 高精度方向预测
- Loop: 处理特殊模式
BOOM v4 分支预测器协作架构详解
1. 整体层次结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| ┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Frontend (前端) │ │ │ │ ┌────────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ BranchPredictor (顶层) │ │ │ │ │ │ │ │ ┌───────────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ ComposedBranchPredictorBank (组合预测器) │ │ │ │ │ │ │ │ │ │ │ │ ┌────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ 预测器级联链 │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ │ │ │ │ │ │ uBTB │───►│ BIM │───►│ BTB │───►│ TAGE │───►│ Loop │───► 最终输出 │ │ │ │ │ │ │ │ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ 基础预测 ──────────────────────────────────────────────────► 精细预测 │ │ │ │ │ │ │ │ (快速) (准确) │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ └───────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ┌───────────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ LocalBranchPredictorBank (本地历史) │ │ │ │ │ └───────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ │ └───────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
2. 预测器级联连接 (核心!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 预测器级联连接详解 │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
来自 config-mixins.scala:603-609 的核心代码:
ubtb.io.resp_in(0) := resp_in // uBTB 接收空输入 bim.io.resp_in(0) := ubtb.io.resp // BIM 接收 uBTB 输出 btb.io.resp_in(0) := bim.io.resp // BTB 接收 BIM 输出 tage.io.resp_in(0) := btb.io.resp // TAGE 接收 BTB 输出 loop.io.resp_in(0) := tage.io.resp // Loop 接收 TAGE 输出
级联图示:
resp_in (全0初始值) │ ▼ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ μBTB (Micro BTB) │ │ │ │ 功能: 超小型全相联 BTB,提供最快的目标地址预测 │ │ 输入: resp_in (空) │ │ 输出: predicted_pc, is_br, is_jal │ │ 特点: F1 阶段就能输出 (最快) │ └─────────────────────────────────────────────────────────────┬───────────────────────┘ │ │ resp ▼ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ BIM (Bimodal Predictor) │ │ │ │ 功能: 2-bit 饱和计数器,提供基础方向预测 │ │ 输入: uBTB 的 resp (透传 predicted_pc, is_br, is_jal) │ │ 输出: 覆盖/设置 taken 预测 │ │ 特点: 简单快速,适合大多数分支 │ └─────────────────────────────────────────────────────────────┬───────────────────────┘ │ │ resp ▼ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ BTB (Branch Target Buffer) │ │ │ │ 功能: 更大的组相联 BTB,提供更准确的目标地址 │ │ 输入: BIM 的 resp (继承 taken) │ │ 输出: 覆盖 predicted_pc, is_br, is_jal (如果命中) │ │ 特点: 支持更大范围的跳转目标 (EBTB) │ └─────────────────────────────────────────────────────────────┬───────────────────────┘ │ │ resp ▼ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ TAGE (Tagged Geometric) │ │ │ │ 功能: 多表历史预测器,基于全局历史提供高精度方向预测 │ │ 输入: BTB 的 resp (使用 taken 作为备选预测) │ │ 输出: 覆盖 taken (如果有表命中且置信度足够) │ │ 特点: 6 个不同历史长度的表,捕捉复杂分支模式 │ └─────────────────────────────────────────────────────────────┬───────────────────────┘ │ │ resp ▼ ┌─────────────────────────────────────────────────────────────────────────────────────┐ │ Loop (Loop Predictor) │ │ │ │ 功能: 专用循环预测器,预测循环退出 │ │ 输入: TAGE 的 resp │ │ 输出: 在检测到循环结束时翻转 taken │ │ 特点: 只有高置信度时才覆盖,保守但精确 │ └─────────────────────────────────────────────────────────────┬───────────────────────┘ │ │ resp (最终输出) ▼ ┌───────────────┐ │ Frontend 使用 │ └───────────────┘
|
3. 信号透传与覆盖机制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ resp_in 透传与覆盖机制 │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
每个预测器的默认行为 (来自 BranchPredictorBank 基类):
io.resp := io.resp_in(0) // 默认透传上游的预测结果
覆盖示例 (以 BTB 为例):
// 默认透传 io.resp.f1(w) := io.resp_in(0).f1(w) io.resp.f2(w) := io.resp_in(0).f2(w) io.resp.f3(w) := io.resp_in(0).f3(w)
// 当 BTB 命中时,覆盖特定字段 when (RegNext(s1_hits(w))) { io.resp.f2(w).predicted_pc := RegNext(s1_resp(w)) // 覆盖目标地址 io.resp.f2(w).is_br := RegNext(s1_is_br(w)) // 覆盖类型 io.resp.f2(w).is_jal := RegNext(s1_is_jal(w)) when (RegNext(s1_is_jal(w))) { io.resp.f2(w).taken := true.B // JAL 强制 taken } }
信号流动可视化:
BranchPrediction 结构: ┌────────────────────────────────────────────────────────────────────────────────────┐ │ taken │ is_br │ is_jal │ predicted_pc │ │ 是否跳转 │ 是否是分支 │ 是否是 JAL │ 目标地址 │ └────────────────────────────────────────────────────────────────────────────────────┘
各预测器的贡献:
字段 uBTB BIM BTB TAGE Loop ──── taken - 设置 (JAL时) 覆盖 翻转(循环结束) is_br 设置 透传 覆盖 透传 透传 is_jal 设置 透传 覆盖 透传 透传 predicted_pc 设置 透传 覆盖 透传 透传 ────
"透传" = 保持上游的值不变 "设置" = 首次提供该值 "覆盖" = 用更准确的值替换 "翻转" = 取反
|
4. 流水线时序与多阶段输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 流水线时序 (F0 → F3) │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
周期 F0 F1 F2 F3 (请求) (访问) (比较) (输出) ─────────────────
μBTB 索引计算 SRAM读取 ───────────► resp.f1 输出 (最快!) ────────► ────────►
BIM 索引计算 SRAM读取 数据返回 ───────────► resp.f2/f3 输出 ────────► ────────► ────────►
BTB 索引计算 SRAM读取 标签比较 ───────────► resp.f2/f3 输出 ────────► ────────► ────────►
TAGE 索引/标签 SRAM读取 Provider选择 预测输出 ──► resp.f3 输出 计算 ────────► ────────►
Loop ───────── 寄存器读取 标签比较 翻转决策 ──► resp.f3 输出 ────────► ────────►
─────────────────
Frontend 使用:
F1 resp: μBTB 提供的快速预测 (可用于下一周期重定向) F2 resp: BIM + BTB 的预测 (更准确) F3 resp: TAGE + Loop 的最终预测 (最准确)
|
5. 更新路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 更新信号流 │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
后端执行单元 │ │ 分支解析结果 ▼ ┌─────────────────────────────────────────────────────────────────────────────────────────────────┐ │ BranchPredictionUpdate │ │ │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────────────┐│ │ │ is_mispredict │ │ is_repair │ │ is_commit │ │ btb_mispredicts ││ │ │ _update │ │ _update │ │ _update │ │ ││ │ │ (投机误预测) │ │ (恢复更新) │ │ (提交更新) │ │ (BTB误预测) ││ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────────────────────┘│ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ pc, br_mask, cfi_idx, cfi_taken, cfi_mispredicted, target, ghist, meta │ │ │ └──────────────────────────────────────────────────────────────────────────────────────────┘ │ └────────────────────────────────────────────┬────────────────────────────────────────────────────┘ │ ┌────────────────────────────┼────────────────────────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐ │ μBTB │ │ BIM │ ... │ Loop │ │ │ │ │ │ │ │ 更新条目 │ │ 更新 2-bit 计数器 │ │ 更新 s_cnt, conf │ └─────────────────────┘ └─────────────────────┘ └─────────────────────┘
更新类型说明: ──────────────── is_commit_update: 分支已提交,确定性更新 (TAGE, BIM 主要使用) is_mispredict_update: 投机路径误预测,需要恢复状态 (Loop 使用) is_repair_update: 修复推测状态 (Loop 用于恢复 s_cnt) btb_mispredicts: BTB 预测错误的目标,需要清除条目
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Meta 数据流 │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
预测时 (打包):
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ μBTB meta│ │ BIM meta │ │ BTB meta │ │TAGE meta │ │Loop meta │ │ (Xbits) │ │ (Ybits) │ │ (Zbits) │ │ (Wbits) │ │ (10bits) │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ │ └──────────────┴──────────────┴──────────────┴──────────────┘ │ ▼ 拼接 ┌─────────────────────────────────────────┐ │ io.f3_meta (合并后) │ │ [Loop | TAGE | BTB | BIM | μBTB] │ └─────────────────────────────────────────┘ │ ▼ 存入 FTQ (Fetch Target Queue) ┌─────────────────────────────────────────┐ │ FTQ Entry │ │ meta 字段保存预测元数据 │ └─────────────────────────────────────────┘
更新时 (解包):
┌─────────────────────────────────────────┐ │ update.bits.meta │ │ 来自 FTQ 的保存的元数据 │ └─────────────────────────────────────────┘ │ ▼ 解包 (从右向左) ┌──────────────┬──────────────┬──────────────┬──────────────┐ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ μBTB │ │ BIM │ │ BTB │ │ TAGE │ │ Loop │ │ 接收自己 │ │ 接收自己 │ │ 接收自己 │ │ 接收自己 │ │ 接收自己 │ │ 的 meta │ │ 的 meta │ │ 的 meta │ │ 的 meta │ │ 的 meta │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
composer.scala 中的解包代码:
var update_meta = io.update.bits.meta for (c <- components.reverse) { // 反向遍历! c.io.update.bits.meta := update_meta update_meta = update_meta >> c.metaSz // 右移剥离 }
|
7. 各预测器职责分工
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 预测器职责分工表 │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌──────────────┬────────────────────────────────────────────────────────────────────────────────────────┐ │ 预测器 │ 职责与特点 │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤ │ │ ■ 提供: 最快的目标地址预测 │ │ μBTB │ ■ 时机: F1 阶段输出 (仅 1 周期延迟) │ │ (Micro BTB) │ ■ 容量: 很小 (全相联,约 16-32 条目) │ │ │ ■ 用途: 快速重定向,减少气泡 │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤ │ │ ■ 提供: 基础方向预测 (taken/not-taken) │ │ BIM │ ■ 时机: F2/F3 阶段 │ │ (Bimodal) │ ■ 容量: 中等 (2048 条目) │ │ │ ■ 用途: 简单分支的快速预测,TAGE 的后备 │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤ │ │ ■ 提供: 准确的目标地址预测 │ │ BTB │ ■ 时机: F2/F3 阶段 │ │ │ ■ 容量: 较大 (128 sets × 2 ways) │ │ │ ■ 用途: 替代 μBTB 的预测 (如果命中),支持远跳转 (EBTB) │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤ │ │ ■ 提供: 高精度方向预测 │ │ TAGE │ ■ 时机: F3 阶段 │ │ │ ■ 容量: 6 个表,不同历史长度 (2/4/8/16/32/64) │ │ │ ■ 用途: 复杂分支模式识别,覆盖 BIM 预测 │ ├──────────────┼────────────────────────────────────────────────────────────────────────────────────────┤ │ │ ■ 提供: 循环退出预测 │ │ Loop │ ■ 时机: F3 阶段 │ │ │ ■ 容量: 小 (16 条目 × bankWidth 列) │ │ │ ■ 用途: 翻转 TAGE 的预测 (当检测到循环即将结束) │ └──────────────┴────────────────────────────────────────────────────────────────────────────────────────┘
|
8. 完整信号流图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 完整信号流图 │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────┐ │ Frontend (前端) │ │ │ │ PC, ghist ──────────────────┐ │ │ │ │ │ f3_fire (预测被使用) ────┐ │ │ │ │ │ │ └────────────────────────────┼──┼────┘ │ │ ┌───────────────────────────────────────────────────────────┘ │ │ │ ▼ ▼ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ BranchPredictor │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ ComposedBranchPredictorBank │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ 预测路径 │ │ │ │ │ │ │ │ │ │ │ │ f0_pc, f0_valid, f1_ghist, f3_fire │ │ │ │ │ │ │ │ │ │ │ │ │ ┌─────────────────────────────┼─────────────────────────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ │ │ μBTB │ │ BIM │ │ BTB │ │ TAGE │ │ Loop │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ F1输出 │ │ F2输出 │ │ F2输出 │ │ F3输出 │ │ F3输出 │ │ │ │ │ │ │ │ target │ │ taken │ │ target │ │ taken │ │ taken │ │ │ │ │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ resp_in │ resp_in │ resp_in │ resp_in │ │ │ │ │ │ │ └────────────►│─────────────►│─────────────►│────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ resp │ │ │ │ │ │ │ │ │ ├───────────────────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ┌────────────────────┴──────────────┴──────────────┴─────────────┴─────────┐ │ │ │ │ │ │ │ meta 打包 │ │ │ │ │ │ │ │ metas = (metas << c.metaSz) | c.io.f3_meta │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────┬────────────┘ │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ io.f3_meta │ │ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ 更新路径 │ │ │ │ │ │ │ │ │ │ │ │ update.bits.meta │ │ │ │ │ │ │ │ │ │ │ │ │ ┌──────────────┬─────────────────────┼─────────────────────┬──────────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ │ │ │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ │ │ │ │ Loop │ │ TAGE │ │ BTB │ │ BIM │ │ μBTB │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ meta解包│ │ meta解包 │ │ meta解包│ │ meta解包│ │ meta解包│ │ │ │ │ │ │ │ update │ │ update │ │ update │ │ update │ │ update │ │ │ │ │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ │ │ │ │ │ │ │ │ ◄──────────────────────────────── update_meta >>= c.metaSz ────────────────────────────── │ │ │ │ │ │ (反向遍历解包) │ │ │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ 输出: io.resp.f1/f2/f3 ──────────────────────────────────────────────────────────────────────────────────────►│ │ │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ │ ▲ │ │ ▼ │ ┌───────────────┐ ┌───────────────┐ │ ICache │ │ 后端 │ │ 取指 │ │ 执行单元 │ └───────────────┘ │ (更新来源) │ └───────────────┘
|
9. takan 信号流动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ taken 字段的流动 │ └─────────────────────────────────────────────────────────────────────────────────────────┘
初始: taken = false (resp_in 全 0) │ ▼ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ μBTB: 不修改 taken │ │ (μBTB 主要提供 predicted_pc) │ └──────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ BIM: taken = counter[1] ← 根据 2-bit 计数器设置 │ │ (BIM 是第一个真正设置 taken 的预测器) │ └──────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ BTB: if (is_jal) taken = true ← JAL 强制跳转 │ │ else taken = 透传 ← 分支保持 BIM 的预测 │ │ │ │ 同时覆盖: predicted_pc, is_br, is_jal │ └──────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ TAGE: if (命中 && 强预测) taken = TAGE 预测 │ │ elif (命中 && 弱预测) taken = 备选预测 或 上游(BTB) │ │ else (未命中) taken = 上游(BTB) ← 这里使用了 BTB/BIM! │ │ │ │ TAGE 未命中时,BIM 的预测通过 BTB 透传过来被使用 │ └──────────────────────────────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ Loop: if (循环结束条件) taken = !上游(TAGE) ← 翻转 │ │ else taken = 上游(TAGE) ← 透传 │ └──────────────────────────────────────────────────────────────────────────────────┘ │ ▼ 最终输出
|
10. 总结:预测器协作的核心思想
1 2 3
| ┌───────────────────────────────────────────────────────────────────────────────────────┐ │ 设计哲学总结 │ └───────────────────────────────────────────────────────────────────────────────────────┘
|
级联覆盖 (Cascaded Override)
每个预测器接收上游的预测,在自己更有把握时覆盖,否则透传。
uBTB → BIM → BTB → TAGE → Loop
│ │ │ │ │
└──────┴──────┴──────┴──────┘
越往右越准确
专业分工 (Specialization)
- 目标预测: μBTB (快), BTB (准)
- 方向预测: BIM (基础), TAGE (复杂模式), Loop (循环)
每个预测器只做自己擅长的事
速度与精度权衡 (Speed-Accuracy Trade-off)
- F1 输出: 快但可能不准 (μBTB)
- F2 输出: 中等 (BIM, BTB)
- F3 输出: 准但慢 (TAGE, Loop)
Frontend 可以根据需要使用不同阶段的预测
元数据保存与恢复 (Meta Preservation)
预测时的内部状态 (meta) 被保存到 FTQ,
更新时解包回各个预测器,
确保更新使用的是预测时的状态,而不是当前状态。
推测更新与确定更新分离
- f3_fire: 预测被前端采用,推测更新 (Loop 的 s_cnt)
- update: 后端确认,确定性训练 (所有预测器)
两条路径相互配合,既保证响应速度,又保证正确性。
这就是 BOOM v4 分支预测器的完整协作机制。核心是级联覆盖设计:简单预测器提供基础预测,复杂预测器在有把握时覆盖,最终形成一个既快速又准确的预测系统。