21. 控制冒险的处理

1. 转移指令对流水线的影响

如下图所示,T1周期取指add指令,T2周期取指sub指令,T3周期取指beq指令。

转移指令对流水线的影响

对于人类来说,我们能看到sub和beq之间可能存在一个循环,但是计算机不知道,它只会在继续取指,T4周期取指lw指令,此时beq指令完成译码阶段但是还不知道要不要跳转。因此T5继续取指sw指令,T5结束时,beq完成执行阶段,此时知道了是否跳转。

如果beq条件满足,即s3 == s4,那么就要跳转到Next执行,lw指令和sw指令实际上就不应该被执行,如下图所示,

beq条件满足,lw指令和sw指令不应该执行

那么T6周期取指sub指令,T7周期取指beq指令,后面又和T4、T5一样了。总体看来就是处理器取回2条正确指令,接着取回2条错误指令(假设beq条件满足),如此反复,流水线的50%性能被浪费了。这是因为转移指令本身和流水线的要求是相违背的。转移指令改变指令流向,破坏了流水模式。

2. 转移指令对性能的影响

如下图所示,转移指令在程序中的占比挺大,因此不能忍受其对流水线的破坏,必须解决,

转移指令对性能的影响

如下图所示,当前流行的处理器超标量数多、流水线级数深,转移指令如果不解决,对处理器的流水线影响太大!

目前流行的处理器结构

3. 转移开销

如下图所示,对于转移指令,必须解决两个问题,一个是转移判定条件,一个是生成目标地址。

转移开销

4. 转移指令的分类

从2个维度分为4类,如下图所示,直接转移指令是把目标地址直接写在指令编码中,而间接转移指令的目标地址放在一个寄存器中,指令需要先访问这个寄存器才可以知道目标地址,

转移指令的分类

5. 无条件转移指令

5.1 直接转移 j Target

如下图所示,因为是无条件转移指令,因此不需要判断是否转移。

无条件直接转移指令

指令编码中就有26-bit立即数,根据计算公式就可以计算出转移目标地址。

根据计算公式,可以看出目标地址只与当前PC寄存器的值和指令编码中的26-bit立即数有关。从数据通路上来看,如下图所示,

从数据通路上看无条件直接转移指令

指令存储器根据PC的值就可以取出指令,在这个取指阶段,加一些硬件电路就可以判断出这是一条无条件直接转移指令,然后PC update部件就是PC+4的值,将这个PC update部件的输出的高4位和指令中的26-bit立即数再和00拼起来,就是转移目标地址了。流水线不需要stall。

5.2 无条件间接转移指令 jr rs

如下图所示,无条件间接转移指令 jr rs,从寄存器堆中读取rs指定的寄存器的内容,将这个数据作为转移目标地址。

无条件间接转移指令

从处理器结构上,来看如何处理无条件间接转移指令,如下图所示,

从数据通路上看无条件间接转移指令

在取指阶段无法确定转移目标地址,因此流水线必须stall一个周期,在译码阶段,busA上的数据就是rs指定的寄存器的数据,利用这个数据就可以计算出转移目标地址。因此,对于无条件间接转移指令,流水线必须stall一个周期。

6. 条件转移指令

如下图所示,beq指令是条件直接转移指令,判断如果R[rs] == R[rt]后,目标转移地址的计算就如下图所示,否则不满足条件,PC的更新就是PC+4. 

条件直接转移指令

我们发现,不论条件是否满足,目标转移地址都只与当前PC寄存器的值和指令编码中的立即数有关,因此目标地址的计算不会stall流水线。

而条件的判断会影响流水线。如下图所示,在译码阶段完成时,rs和rt指定的寄存器的数据输出在busA上和busB上,但此时还无法判断两个寄存器的数据是否相等。在执行阶段完成时,ALU输出就可以判断两个寄存器是否相等了,因此流水线需要stall两个周期。

从处理器结构上看beq指令的执行

但其实,判断rs和rt指定的寄存器的数据是否相等很简单,对寄存器堆做一点改造就可以在译码阶段完成判断。如下图所示,这样,流水线只需要stall一个周期,beq指令对流水线的影响降低了,

在寄存器堆的输出加一个判断电路完成数据相等判断

7. 控制冒险的影响总结

综上,我们发现,

无条件直接转移指令 j Target 不会stall流水线

无条件间接转移指令 jr rs 会stall一个周期

条件直接转移指令 beq rs,rt,imm16 会stall一个周期

8. 进一步优化,不让转移指令影响流水线

8.1 延迟转移技术

如下图所示,xor指令,addi指令,subi指令后,跟着一条beq指令,beq指令stall流水线1个周期后,会判断转移还是不转移,这里流水线就空出了一个周期,我们可以在这个周期中插入一条指令而不影响流水线。

延迟转移技术举例

那么就向上去找,addi指令和subi指令都与beq指令依赖,但是xor指令与beq指令没有依赖,就可以调整指令顺序,将xor指令放在beq指令后面执行,那么流水线就不需要stall了。如下图所示,这样beq指令取指后进入译码阶段,xor指令就可以进入流水线取指,xor取指后,beq就完成了条件判断,知道是否转移了。这样,流水线就不需要stall了。

调整指令顺序

你可能感兴趣的:(21. 控制冒险的处理)