赞
踩
一条指令的执行过程分为以下5个周期:
PC
中的内容作为地址,从存储器中取出指令并放入指令寄存器IR
;PC
值加4
(假设每条指令占4个字节),指向顺序的下一条指令。IR
中的寄存器地址去访问通用寄存器组,读出所需的操作数。在这个实现方案中:
将上述实现方案修改为流水线实现:
IF段
的访存(取指令)与MEM段
的访存(读/写数据)发生冲突。
ID
段和WB
段都要访问同一寄存器文件。
PC
的处理
3
种类型
i
(在前,下同)和j
(在后,下同),如果下述条件之一成立,则称指令j
与指令i
数据相关。
j
使用指令i
产生的结果,指令j
与指令i
数据相关;j
与指令k
数据相关,而指令k
又与指令i
数据相关。例:下面这一段代码存在数据相关。
Loop: L.D F0,0(R1) // F0为数组元素
ADD.D F4,F0,F2 // 加上F2中的值
S.D F4,0(R1) // 保存结果
DADDIU R1,R1,-8 // 数组指针递减8个字节
BNE R1,R2,Loop // 如果R1≠R2,则分支
名:指令所访问的寄存器或存储器单元的名称。
如果两条指令使用相同的名,但是它们之间并没有数据流动,则称这两条指令存在名相关。
指令j
与指令i
之间的名相关又分为两种(j
后进入):
反相关:如果指令j
写的名与指令i
读的名相同,则称指令i
和j
发生了反相关。
指令j写的名=指令i读的名
输出相关:如果指令j
和指令i
写相同的名,则称指令i
和j
发生了输出相关。
指令j写的名=指令i写的名
名相关的两条指令之间并没有数据的传送。因此,如果一条指令中的名改变了,并不影响另外一条指令的执行。
换名技术
例:DIV.D
和ADD.D
存在反相关。
DIV.D F2,F8,F4
ADD.D F8,F0,F12
SUB.D F10,F8,F14
进行寄存器换名(F8
换成S
)后,变成
DIV.D F2,F8,F4
ADD.D S,F0,F12
SUB.D F10,S,F14
示例:典型的“if-then”结构
if p1 {
S1;
};
S;
if p2 {
S2;
};
控制相关带来了以下两个限制:
与一条分支指令控制相关的指令不能被移到该分支之前。否则这些指令就不受该分支控制了。
如果一条指令与某分支指令不存在控制相关,就不能把该指令移到该分支之后。
流水线冲突是指对于具体的流水线来说,由于相关的存在,使得指令流中的下一条指令不能在指定的时钟周期执行。
流水线冲突有3种类型
:
流水线冲突带来的问题:
举例:访存冲突
有些流水线处理机只有一个存储器,将数据和指令放在一起,访存指令会导致访存冲突。
如上图中:由于流水的设置,指令i+3
与load指令
需要同时访问存储器
指令存储器
和数据存储器
、或设置相互独立的指令Cache
和数据Cache
。有时流水线设计者允许结构冲突的存在
当相关的指令靠得足够近时,它们在流水线中的重叠执行或者重新排序会改变指令读/写操作数的顺序,使之不同于它们串行执行时的顺序,则发生了数据冲突。
根据指令读访问和写访问的顺序,可以将数据冲突分为3种类型
。
i
和j
,且i在j之前
进入流水线,可能发生的数据冲突有:
i
写入之前,j
先去读。 j
读出的内容是错误的。在 i
写入之前,j
先写。最后写入的结果是i写入
的。错误!
这种冲突对应于输出相关。
写后写冲突仅发生在这样的流水线中:
前面介绍的5段流水线不会发生写后写冲突。原因:只在WB段
写寄存器
i
读之前,j
先写。i
读出的内容是错误的!⚠️(这几种冲突的名字实际上是正确执行的顺序,冲突的含义是这一顺序被颠倒了)
通过定向技术减少数据冲突引起的停顿
关键思想:
解释如下:
采用定向技术后的流水线数据通路如下图所示:
定向的实现:
EX段
和MEM段
之间的流水寄存器中保存的ALU运算结果
总是回送到ALU的入口
。前一个ALU运算结果
写入的寄存器就是当前ALU操作的源寄存器
时,那么控制逻辑就选择定向的数据作为ALU的输入
,而不采用从通用寄存器组读出的数据。⚠️并不是所有的数据冲突都可以用定向技术来解决
例如:无法将LD
指令的结果定向到DADD
指令
LD R1,0(R2)
DADD R4,R1,R5
AND R6,R1,R7
XOR R8,R1,R9
解决方法:
依靠编译器解决数据冲突
例:为下列表达式生成没有暂停的指令序列:
A=B+C;
D=E-F;
假设载入延迟为1个时钟周期。
题解:
LD Rb,B
LD Rc,C
DADD Ra,Rb,Rc #注意到此处存在冲突
SD Ra,A
LD Re,E
LD Rf,F
DSUB Rd,Re,Rf
SD Rd,D
解释:如图所示,LD指令以及DADD指令存在数据冲突,LD指令在MEM段取出的数据在DADD指令的EX段就需要使用,因此若两条指令相邻只想,则会产生,冲突,若是在这两条指令直接插入一条“指令”,即可解决这一问题,更进一步的是,若由编译器调度一条独立的指令在LD指令以及DADD指令之间,则完全不会影响流水线的运行。
一种调度方式如下所示:
LD Rb,B
LD Rc,C
LD Re,E
DADD Ra,Rb,Rc
LD Rf,F
SD Ra,A
DSUB Rd,Re,Rf
SD Rd,D
执行分支指令的结果有两种
处理分支指令最简单的方法:“冻结”或者“排空”流水线
优点:简单
分支指令 | IF | ID | EX | MEM | WB | |||||
---|---|---|---|---|---|---|---|---|---|---|
分支目标指令 | IF | stall | stall | IF | ID | EX | MEM | WB | ||
分支目标指令+1 | IF | ID | EX | MEM | WB | |||||
分支目标指令+2 | IF | ID | EX | MEM | ||||||
分支目标指令+3 | IF | ID | EX |
ID段
完成,即分支指令是在ID段的末尾
执行完成,所带来的分支延迟为一个时钟周期。3种
通过软件(编译器)来减少分支延迟的方法
共同点:
1. 预测分支失败
2. 预测分支成功
3. 延迟分支的方法
分支失败的情况:
分支指令 i | IF | ID | EX | MEM | WB | ||||
---|---|---|---|---|---|---|---|---|---|
延迟槽指令 i+1 | IF | ID | EX | MEM | WB | ||||
指令 i+2 | IF | ID | EX | MEM | WB | ||||
指令 i+3 | IF | ID | EX | MEM | WB | ||||
指令 i+4 | IF | ID | EX | MEM | WB |
分支成功的情况:
分支指令 i | IF | ID | EX | MEM | WB | ||||
---|---|---|---|---|---|---|---|---|---|
延迟槽指令 i+1 | IF | ID | EX | MEM | WB | ||||
指令 i+2 | IF | ID | EX | MEM | WB | ||||
指令 i+3 | IF | ID | EX | MEM | WB | ||||
指令 i+4 | IF | ID | EX | MEM | WB |
分支延迟指令的调度
调 度 策 略 | 对调度的要求 | 什么情况下起作用 |
---|---|---|
从 前 调 度 | 被调度的指令必须与分支无关 | 任何情况 |
从目标处调度 | 必须保证在分支失败时执行被调度的指令不会导致错误。有可能需要复制指令。 | 分支成功时 (但由于复制指令,有可能会增大程序空间) |
从失败处调度 | 必须保证在分支成功时执行被调度的指令不会导致错误。 | 分支失败时 |
预测分支失败的情况下,分支取消机制的执行情况
分支指令 i | IF | ID | EX | MEM | WB | ||||
---|---|---|---|---|---|---|---|---|---|
延迟槽指令 i+1 | IF | idle | idle | idle | idle | ||||
指令 i+2 | IF | ID | EX | MEM | WB | ||||
指令 i+3 | IF | ID | EX | MEM | WB | ||||
指令 i+4 | IF | ID | EX | MEM | WB |
预测分支成功的情况下,分支取消机制的执行情况:
分支指令 i | IF | ID | EX | MEM | WB | ||||
---|---|---|---|---|---|---|---|---|---|
延迟槽指令 i+1 | IF | ID | EX | MEM | WB | ||||
分支目标指令j | IF | ID | EX | MEM | WB | ||||
分支目标指令j+1 | IF | ID | EX | MEM | WB | ||||
分支目标指令j+1 | IF | ID | EX | MEM | WB |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。