“转发解决已经算出但尚未写回的值,互锁处理还没算出的值,分支清除处理根本不该执行的指令。这三个机制的对象不同。”
形式陈述
在本单元五级模型中,beq在EX读取经过转发的两个源值,周期末决定是否跳转及目标;IF此前按PC+4连续取指。若跳转成立,本周期ID和IF中的两条年轻指令属于错误路径。
恢复动作是在该边沿把下一取指PC设为目标、将下一IF/ID和ID/EX置为无效。分支本身和更老指令继续前进。下一周期IF开始取目标,因此此模型的一次taken分支引入两个空发射位置。未跳转没有此罚时。
这里的“按未跳转预测”是实现策略,flush是取消错误推测的机制。RV32I没有架构可见的分支延迟槽,不允许把分支后的第一条错误路径指令保留下来执行。
直觉
分支决断晚于取指,处理器先走了一段尚未获准的路。只要这些年轻指令还没有产生无法撤回的架构副作用,就可以把valid清零,再从正确目标重新开始。
清除的是指令的有效身份,不是把所有数据导线都擦成零。无效槽里即使还残留地址或旧值,也必须因valid和写使能的约束而不能写寄存器或内存。
例子与边界
被取到的store不应被执行
取下面片段,x4=0,x7=11:
0x10: beq x4,x0,+12
0x14: sw x7,0(x1)
0x18: addi x6,x0,99
0x1c: lw x5,0(x1)
当beq在EX时,store在ID、addi在IF。EX末比较相等,目标
数据冒险先决定分支条件
若beq紧随 lw x4,32(x1),且旧x4=1、load将读得0,应先经load-use互锁,随后用load的0作比较。用ID读出的旧1会错误地不跳转;即便flush逻辑本身正确,也救不了错误条件。
罚时不是指令集常量
另一个实现若到MEM才重定向,可能要清除三个年轻位置;若在ID可靠地完成比较,也可能更早恢复。两者都可以实现相同ISA。本文的两槽结论只由“EX末决断、每周期单发、下周期目标IF”三项条件推出。
若目标恰好已经在某个年轻槽内,本文仍按统一规则清除并重新取它,没有额外复用优化。计算周期不能一会儿采用统一flush,一会儿暗中保留碰巧正确的指令。
推论与应用
分支恢复的安全性来自副作用的先后关系:本文年轻store尚未到MEM,年轻寄存器写尚未到WB。更激进的实现必须用其他办法延迟提交,不能只照抄两个valid位的清零。
完整终点任务在周期9做taken恢复;错误路径store正好是可核验反例。正确轨迹不含这次访问,因此缓存模拟器也不应凭“取指看见过store”就把它加入数据trace。
参考资料
- RISC-V International,RV32I 2.1,固定文档版 v20260120,§1.1.5,控制转移没有架构可见延迟槽。
- UC Berkeley CS61C,Control Hazards,课程笔记,访问于 2026-10-08。该笔记的示意模型在MEM重定向;本页明确选EX末重定向,清除数量由本页规则推导。