CS152 · 第 12 课

Out-of-order Execution I:两种真实重命名设计

第 11 课确立了"重命名 + ROB"的基本框架。这一课把它变成两种真实处理器都采用过的具体工程方案——数据放在 ROB 里,还是放进一个统一的物理寄存器堆——并讲清楚每种设计各自需要维护哪些结构。

授课:Sophia Shao 预计用时:60 分钟 难度:较难

流水线阶段的顺序 vs. 乱序(术语澄清)

取指/译码/重命名永远按程序顺序进行(必须按顺序解析 ISA);派发(Dispatch)——把指令放进机器缓冲区等待发射——同样永远按顺序进行(本课程明确约定:"有人把 Dispatch 等同于 Issue,但本课不这样用")。顺序发射(InO issue):遇到 RAW/结构冒险(可能还有 WAR/WAW)就停顿,不能跳过更早的未发射指令;乱序发射(OoO issue):指令按程序顺序进入保留站/发射缓冲等待操作数,之后可以不按顺序发射。完成(completion)几乎在所有真实机器上都是乱序的(不同功能单元延迟不同);即使是"经典 RISC 5 级流水线",也只是"勉强"做到顺序完成(2 周期的 load 恰好和后面 1 周期的运算指令同时完成,而非更早)。提交(commit):顺序提交⇒精确陷阱(今天的标准做法);早期乱序机器的"完成即提交"造成了不精确陷阱。


设计一:Data-in-ROB(真实例子:HP PA8000、Pentium Pro、Core2Duo、Nehalem)

ROB 条目直接持有操作数标签/数值和结果:v(valid)、i(issued)、Opcode、p|Tag|Src1、p|Tag|Src2、p|Reg|Result|Except?;标签就是 ROB 索引本身(派发时的 Free 指针值)。规则:派发时,源操作数如果对应寄存器不"忙",就直接从架构寄存器堆读入 Src1/Src2 并置位 p;如果"忙",就复制生产者指令的标签,p 置零。完成时,在整个 ROB 里搜索/匹配等待这个标签的源操作数字段,把数据拷贝进去并置位 p。提交时检查异常状态,若无陷阱则把结果写入架构寄存器堆;若发生陷阱,清空整台机器和 ROB,Free 指针回退到最旧的未提交指令,跳转到陷阱处理程序。


设计二:统一物理寄存器堆(真实例子:MIPS R10K、Alpha 21264、Intel Pentium 4、Sandy/Ivy Bridge)

重命名在译码阶段直接把架构寄存器映射到一个共享的物理寄存器堆里的具体物理寄存器(此时不读取数值);功能单元直接读写这个唯一的物理寄存器堆;提交只更新架构→物理寄存器的映射表,不涉及任何数据搬运——这是它和 Data-in-ROB 设计的根本区别:Data-in-ROB 需要在完成/提交时把数据在 ROB 和架构寄存器堆之间搬来搬去,而统一物理寄存器堆设计里数据从一开始就待在物理寄存器堆原地不动,只是"名字"在变。

物理寄存器的生命周期:一个物理寄存器可以被回收复用的时机,是"同一个架构寄存器的下一个写者提交之后"——因为在那之前,旧的物理寄存器仍然可能是某个尚未提交指令所需的正确值。每条指令的 ROB 条目除了常规字段外,还需要记录 PRd(本指令新分配的物理寄存器)和 LPRd(这个逻辑目的寄存器在本指令之前映射到的上一个物理寄存器)——LPRd 用于在分支预测错误或异常时恢复映射表,也用于判断旧物理寄存器何时可以被释放。

陷阱发生时如何修复重命名表:MIPS R10K 按相反顺序、利用每条指令的 PRd/LPRd 字段逐条"反向撤销重命名"来修复重命名表;Alpha 21264 则采取完全不同的策略——为每一条 ROB 指令都保留一份完整的重命名表快照(共 80 份),出错时直接把某一份快照整体"闪回",一个周期内完成。两种方案的权衡很直接:MIPS R10K 省快照存储空间但恢复较慢(要逐条撤销);Alpha 21264 用大量存储空间换取单周期恢复。


发射窗口为什么要与 ROB 分开设计?

ROB 是一个滑动窗口:每个周期由"提交"移除最旧的一批指令,"执行"填充中间部分,"取指"在最新端加入新指令。发射窗口可以与 ROB 完全分离:发射窗口只持有"已译码/重命名但尚未发射"的指令(字段 use/ex/op/p1/PR1/p2/PR2/PRd/ROB#,其中 ROB# 指回该指令在 ROB 中的条目);ROB 本身只需要保存提交所需的信息(Done?/Rd/LPRd/PC/Except?)。幻灯片提出了一个留给课堂讨论的问题:"ROB 通常比发射窗口大好几倍——为什么?"(幻灯片本身没有给出答案:直觉上,一条指令完成执行后往往还要在 ROB 里等待很久才轮到提交,而发射窗口只需要容纳"尚未发射"的这一小段,因此 ROB 需要覆盖的时间跨度天然更长。)


常见误区


知识检查

问题 1:"Data-in-ROB"设计和"统一物理寄存器堆"设计最根本的区别是什么?

问题 2:一个物理寄存器什么时候才可以被安全地释放、复用给新指令?

问题 3:MIPS R10K 和 Alpha 21264 在"陷阱发生后如何修复重命名表"这件事上分别采用了什么策略?


本课要点

术语澄清

Dispatch/Issue/Complete/Commit 各自顺序还是乱序

Data-in-ROB

数据存在 ROB 里,标签=ROB 索引,需要搬运数据

统一物理寄存器堆

数据原地不动,提交只改映射;PRd/LPRd 追踪生命周期

快照 vs. 反向撤销

Alpha 21264 用 80 份快照单周期恢复;MIPS R10K 逐条撤销更省空间


参考资料与延伸阅读