目录
一、基础知识
1、每个阶段的含义
2、为何要产生阻塞
3、何时才能产生阻塞
4、产生阻塞的条件
5、产生阻塞的流程以及后续情况
6、特殊情况
二、具体问题分析
一、基础知识
1、每个阶段的含义
2、为何要产生阻塞
上一条需要写寄存器指令的目的寄存器与当前指令的源寄存器相同,使得当前指令需要用到上一条指令的结果,若顺序执行,由于上一条指令还未写入寄存器,使得本条指令源寄存器中的数据不是正确的,那么EX阶段得到的结果也是错误的,所以为了得到正确的数据,不得不等待上一条指令将结果写回到目的寄存器中或者可能需要等待旁路得到正确指令。即产生阻塞。
无转发和有转发的区别:
无转发不能在中间过程得到所需的数据。只能等待上一条指令的WB阶段执行时,才能同时执行ID阶段。(一个时钟周期内,前半个时钟周期WB先写入寄存器,后半个时钟周期ID读取寄存器,先写后读,各占一半,所以WB和ID可以同时进行,ID可以取到正确的数据)
有转发可以在中间阶段从流水线寄存器组里通过旁路得到所需要的数据。只要流水线寄存器组内有了需要的值即可。
3、何时才能产生阻塞
要得知是否产生阻塞,则需要得知上一条指令是什么,以及当前指令是什么(因为只有Write after Read才可能阻塞)。而得知指令具体是什么,在IF阶段(通过PC中的指令地址在指令存储器中取指令)是不能得知的,只能在ID阶段(指令译码和读寄存器堆)进行译码才能得知当前指令与上一条指令是否需要产生阻塞。
所以即使是如下指令:
lw $t0,200($s0)
add $t1,$t0,$s1
在lw进行ID阶段时,add指令也一定会执行IF阶段,因为此时是不知道是否产生阻塞的。
指令执行情况:
4、产生阻塞的条件
对于每一条指令,对应阶段的流水线寄存器会保存该指令的数据和控制信号。
(1)无转发(无旁路):
第一种情况:只能等待上一条指令的结果写回寄存器
①ID/EX.RegWrite=1//上一条是写寄存器的指令,包括lw和add等
②上一条写指令的目的寄存器与当前源寄存器冲突
第二种情况:间隔阻塞
lw $t1,2304($t0)
sub $0,$s3,$t2
add $s1,$t1,$0//t1必须等第一条lw的t1取回才行。
(2)有转发:
①ID/EX.MemRead=1 //上一条指令是存储器读指令,即lw指令
②ID / EX.RegisterRt = IF/ID. RegisterRs orID/ EX.RegisterRt = IF/ IDRegisterRt //上一条指令的目的寄存器和本条指令的源寄存器相同
5、产生阻塞的流程以及后续情况
基本认知:
当流水线发生阻塞时,阻塞的流水线寄存器和PC保持数据不变,直到可以执行时才开始顺序执行,即当前指令发生阻塞,同样表现为以后的指令阻塞。阻塞是通过产生空指令实现的,而锁定不变的部分,但是同样会往前执行,只是锁定的内容不再更改。
因为是顺序执行的,当前指令在执行当前阶段时,下一条指令只可能执行上一阶段。
如(随便举个例子,不用考虑实际第一条指令和第二条指令为什么是这样的):
---------------------------------------------------------------------------------------------------------------------------------
无转发:若上一条指令是写寄存器指令,由于不能通过旁路得到正确数据,则必须从寄存器里取得,所以当前指令的ID阶段 必须等到 上一条指令的WB阶段时才能执行。
当前指令地址给PC,PC经过IF,数据存入IF/ID,PC=PC+4;继续执行到ID译码,发现前一条写指令的目的寄存器和当前指令的源寄存器相同,锁定PC和IF/ID保持不变,对ID阶段的控制清0(这些控制信号在每个时钟周期都向前传递, 但不会产生不良后果,因为如果控制信号都是0, 那么所有寄存器和存储器都不进行写操作,相当于只是推迟ID的执行),直到上一条指令执行到WB,解锁PC和IF/ID,不再清0控制。
A:lw $t0,200($s0)
B: add $t1,$t0,$s1
C:addi $t1,$t1,2304
D:sub $s1,$s2,$s3
---------------------------------------------------------------------------------------------------------------------------------
有转发:
当前指令地址给PC,PC经过IF到IF/ID,PC=PC+4(下一条指令地址给PC),继续执行到ID译码(并且同时进行的IF阶段),发现前一条指令的目的寄存器和当前指令的源寄存器相同,锁定PC和IF/ID保持不变,此时并不需要对ID阶段的控制清0,因为我们只用在EX阶段取到正确的值即可,这个值可来源于旁路。所以只对EX阶段的控制清0,这样ID实际上是执行了的(锁定ID/EX实际上也行,不锁定也行),因为IF/ID的数据一直在往前送,直到上一条指令执行完MEM,解锁PC和IF/ID,不再清0控制,再一起往前运行。
A:lw $t0,200($s0)
B: add $t1,$t0,$s1
C:addi $t1,$t1,2304
6、特殊情况
①取最近旁路的值
两种旁路,第一种答案可从EX/MEM中取得,第二种答案可从MEM/WB中取得。
情况:
一个指令的两个源寄存器分别是上两个指令的目的寄存器。如:
add $s0,$t0,$t1
add $t1,$t2,$t0
add $s1,$s0,$t1
这时,当第三条add到ALU输入时,第二条已经ALU运算完了,结果在EX/MEM里可以取出,第一条已经到MEM/WB里,可以取出
一个指令的一个源寄存器是上两个指令的目的寄存器。如:
add $t1,$t0,$t1
add $t1,$t2,$t0
add $s1,$s0,$t1
这时第二条已经ALU运算完了,结果在EX/MEM里可以取出,第一条已经到MEM/WB里,可以取出,但是第三条需要的t1是最新的t1也就是第二条指令里面的t1,所以它需要从最新的EX/MEM中取出。阻断MEM/WB的。
一个指令的一个源寄存器是上一个指令的目的寄存器或者是上上一个指令的目的寄存器。
②$0寄存器不接受旁路
add $0,$t1,$t2
add $t3,$0,$t1
上一条指令的目的寄存器为$zero不接受旁路。并不是$zero的值被修改了,实际上零号寄存器的值没有被修改。上一条指令的ALU的计算结果放在了EX/MEM流水线寄存器组里面,这个时候的结果并没有传给$zero,而此时目的寄存器实实在在确实是$zero,也就是说,它会误认为现在EX/MEM流水线寄存器组里面的值就是需要的结果值,也就ID/EX.RS=EX/MEM.Rd成立,所以会把结果值通过旁路拿出来,但实际上$zero还是那个zero。这种命令它只判断目的寄存器是否为源寄存器,然后把流水线的值转发给ALU,这个流水线的值实际上并不是目的寄存器的现有值。实际上需要在旁路的判断条件上加上EX/MEM.Rd≠$zero,所以$0寄存器不接受旁路,而直接采用当前值。
二、具体问题分析
①无转发
无转发,ID必须等到上一条指令写回才能运行。所以遇到写指令的目的寄存器和源寄存器相同,就得将ID推迟到上一条指令的WB。
②有转发
文章来源:https://www.toymoban.com/news/detail-477956.html
文章来源地址https://www.toymoban.com/news/detail-477956.html
到了这里,关于处理器流水线——时空图作图原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!