Lec 06 流水线处理器
MIT 6.1920 · Constructive Computer Architecture 讲师:Arvind · 日期:2024-02-22
1. 流水线的动机
非流水线处理器 CPI ≈ 2–3;流水线目标:CPI → 1,使各阶段硬件同时忙碌。
定义 — 4 级流水线(4-Stage Pipeline)
将指令执行分为 4 个流水级,每级用级间寄存器(pipeline register)暂存中间结果:
Fetch(IF)→ Decode(ID)→ Execute(EX)→ Writeback(WB)
访存(MEM)并入 Execute 或 Writeback 阶段。
将指令执行分为 4 个流水级,每级用级间寄存器(pipeline register)暂存中间结果:
Fetch(IF)→ Decode(ID)→ Execute(EX)→ Writeback(WB)
访存(MEM)并入 Execute 或 Writeback 阶段。
2. BSV 4 级流水线结构
2.1 级间 FIFO
bsv
FIFO#(Fetch2Decode) f2d <- mkPipelineFIFO;
FIFO#(Decode2Execute) d2e <- mkPipelineFIFO;
FIFO#(Maybe#(Exec2WB)) e2w <- mkPipelineFIFO;2.2 各级规则
bsv
rule fetch;
iMem.enq(pc[1]);
f2d.enq(Fetch2Decode{pc: pc[1], epoch: epoch[1]});
pc[1] <= pc[1] + 4;
endrule
rule decode;
let inst = iMem.first; iMem.deq;
let x = f2d.first; f2d.deq;
let dInst = decode(inst);
d2e.enq(Decode2Execute{dInst, pc: x.pc, epoch: x.epoch, ...});
endrule
rule execute;
let x = d2e.first; d2e.deq;
if (x.epoch != epoch[0])
e2w.enq(Invalid); // 冲刷无效指令
else begin
let eInst = exec(x.dInst, rVal1, rVal2, x.pc);
if (mispredicted) begin pc[0] <= correct_pc; epoch[0] <= epoch[0]+1; end
e2w.enq(Valid(Exec2WB{eInst, pc: x.pc}));
end
endrule
rule writeback;
let vx = e2w.first; e2w.deq;
if (vx matches tagged Valid .x) begin
if (isValid(x.eInst.dst)) rf.wr(...);
if (x.eInst.iType == Ld) dMem.deq;
end
sb.remove;
endrule3. 数据冒险(Data Hazard)
定义 — 读后写冒险(RAW Hazard, Read-After-Write)
当指令 i2 的源寄存器与尚未写回的指令 i1 的目标寄存器相同时,出现 RAW 冒险。若不处理,i2 将读到旧值。
当指令 i2 的源寄存器与尚未写回的指令 i1 的目标寄存器相同时,出现 RAW 冒险。若不处理,i2 将读到旧值。
3.1 计分板(Scoreboard)
用于跟踪"哪些寄存器正在被流水线中的指令写":
bsv
interface Scoreboard;
method Action insert(Maybe#(RIndx) dst); // 指令进入 Decode 时登记
method Action remove; // 指令完成 Writeback 时释放
method Bool search1(Maybe#(RIndx) src); // 检查 src 是否"脏"
method Bool search2(Maybe#(RIndx) src);
endinterfaceDecode 阶段检查冒险:
bsv
let stall = sb.search1(dInst.src1) || sb.search2(dInst.src2);
if (!stall) begin
sb.insert(dInst.dst);
d2e.enq(...);
f2d.deq; iMem.deq;
end // stall: 不 deq,保持 f2d 和 iMem 不动推论 — 旁路(Bypassing / Forwarding) 计分板 stall 会降低 CPI。旁路网络(forwarding network)将 EX/MEM 阶段的计算结果直接送回 Decode 或 Execute 阶段作为源操作数,消除大多数 RAW stall,使 CPI 接近 1。
4. 控制冒险(Control Hazard)
定义 — 控制冒险与 Epoch(Control Hazard & Epoch)
分支/跳转指令在 Execute 阶段才确定真实目标,而 Fetch 已提前取了下一条指令。若预测错误,需冲刷(flush)流水线中错误路径上的指令。BSV 用纪元计数器(epoch)标记每条指令所属时代,Execute 检测到错误预测时递增 epoch,后续各级遇到旧 epoch 的指令直接丢弃。
分支/跳转指令在 Execute 阶段才确定真实目标,而 Fetch 已提前取了下一条指令。若预测错误,需冲刷(flush)流水线中错误路径上的指令。BSV 用纪元计数器(epoch)标记每条指令所属时代,Execute 检测到错误预测时递增 epoch,后续各级遇到旧 epoch 的指令直接丢弃。
冲刷机制流程:
- Execute 发现 ppc ≠ 真实 nextPc
pc[0] <= correct_pc; epoch[0] <= epoch[0] + 1;- Decode / Writeback 中旧 epoch 指令 →
e2w.enq(Invalid) - 计分板也需同步清理
5. 流水线性能
例题 — 流水线 CPI 估算
假设:分支占 20%,预测全部 pc+4,分支实际 taken 60%;无 RAW stall(假设有旁路):
- 分支错误率 = 20% × 60% = 12%
- 每次分支错误冲刷 3 条指令(4 级流水)
- CPI =
Sol:提升分支预测精度(加 BTB、BHT)可将 CPI 降低至接近 1。
本讲总结
4 级 BSV 流水线通过级间 FIFO 和 epoch 机制实现正确的指令执行;计分板防止 RAW 冒险;epoch 机制处理控制冒险;旁路网络消除 stall,是提升 CPI 的关键硬件投入。