1.结构冒险
定义:同一个部件同时被不同指令所使用而引起的流水线阻塞。
正如上面的Load
和Instr 3
指令的Mem
和Reg
两处都发生了结构冒险[Mem
同时使用了存储器,Reg
同时使用了寄存器]。
解决办法:
正如上面的Load
和Instr 3
指令的Mem
和Reg
两处都发生了结构冒险[Mem
同时使用了存储器,Reg
同时使用了寄存器]。
2.数据冒险
2.1普通结构冒险
定义:后面指令要用到前面指令产生的结果而前面的结果还没产生而引起的流水线阻塞。
正如上面的sub
、and
、or
和xor
都要用到add
产生的r1,但r1在WB阶段才产生,因此存在以下问题:
解决办法:
方法1: 转发技术
定义:当后面指令要用到前面指令的结果数据时,前面流水线部件中得到的数据直接通过连线传送到后面流水段的部件中,而不等前面指令的结束。这种方式称为转发或旁路,它能解决部分数据冒险。
方法2:合理实现寄存器堆的读/写操作
前半时钟周期写,后半时钟周期读,若同一个时钟内前面指令写入的数据正好是后面指令所读数据,则不会发生数据冒险
- 在
sub
处使用转发技术,让add
在ALU的运算结果直接传到sub
的Reg
处 - 在
and
处使用转发技术,让add
在ALU或Dm的运算结果直接传到and
的Reg
处 - 在
or
处使用转发技术,让add
在Reg前半部分产生结果,然后将结果在后半部分直接传到or
的Reg
处
2.2.Load-use结构冒险
定义:和普通结构冒险差不多,后面的非Load指令要用到前面的Load指令产生的结果而前面的结果还没产生而引起的流水线阻塞。
解决办法:
合理调整指令指令顺序
3.控制冒险
定义:由于发生了指令执行顺序的改变引起的流水线阻塞。
如上图的Beq
指令,是一条转移指令,到Mem
才知道要转移到1000:Target of Br
指令,但这是已经执行了16
、20
和24
这三条指令了,因此取错了三条指令。