|
发表于 2013-10-27 10:37:22
|
显示全部楼层
本帖最后由 lipizju 于 2013-10-27 10:45 编辑
Stall 的产生是指因为当前指令需要的某些信息还没有available而导致其无法继续在流水线中前进, 注意此时还没有任何的 speculative execution happens.
Stall 的目的是等待当前指令需要的信息准备好即wait till dependency to be resolved, 然后可以继续执行, 至于你提到的stall 加在哪里, I think that's a good question,
我的答案是 : no early than current instruction gets to know the data it needs can not be available, no later than error data reading happens,
Mips 的pipeline 设计非常巧妙, 我们可以最早在second stage ID 级就可以detect all data dependency, so 我们一般就stall ID stage, which means keep IF/ID interface
register unchanged and insert a bubble into ID/EX interface register:
IF/ID ID/EX EX/MEM MEM/WB
cycle one: current inst previous inst previous of previous
cycle two: current inst bubble(nop) previous inst previous of previous
至于你提到的为什么不在IF stage stall 是因为那时指令还未进入流水线, current inst还不知道自己需要的data是否available
当然以上提到的情况是在没有data forwarding path的情况下, 如果在data path 上加上一些简单的mux 和 control register, 我们就可以解决绝大部分
(except delayed load, still need one cycle stall for back to back dependency) data dependency 而不用stall, 这样就可以improve over all throughput
至于flush则是因为pipeline 由于speculative execution 而产生了错误的状态,这时我们无法通过插入stall cycle来解决, 而只能把错误的register清零,
IF/ID ID/EX EX/MEM MEM/WB
cycle one: speculative one Branch inst previous inst
cycle two: Flush/bubble Flush/bubble Branch inst previous inst
flush 操作一般用在resolve control dependency, 因为对于BNE or BEQ, next instr address is resloved in EX stage, 如果我们要等待的话需要stall two cycles
that's too expensive, so generally, mips will use some kind of branch prediction to reduce the cost, 就像最简单的predic branch never happens, 如果预测错误
的话我们必须flush branch inst 之后的所有instrctions, that is also expensive, so mips ISA introduce the delay slot mechanism to allow the following inst to finish |
|