本次笔记内容:
P27 计算机组成原理(27)
P28 计算机组成原理(28)
P29 计算机组成原理(29):前24分钟
本节课对应幻灯片:
结构冲突:在同一时刻,由于指令重叠执行,不同指令争用同一硬件资源。
数据冲突:由于指令重叠执行,造成指令间执行步骤的相对时间发生变化,后续指令无法在预期的位置得到正确的源操作数。
此外,数据冲突还可以使用动态调度
:
指令顺序发射——乱序执行——指令乱序流出
动态调度
的内容将在系统结构
中讲解。
流水线的控制冲突
是因为程序执行转移类指令
而引起的冲突。转移类指令如无条件转移、条件转移、子程序调用、中断等,它们属于分支指令,执行中可能改变程序的方向,从而造成流水线断流。
数据冲突
影响到的仅仅是本条指令附近少数几条指令,所以称为局部冲突
。而控制冲突
影响的范围要大得多,它会引起程序执行方向的改变,使流水线损失更多的性能,所以称为全局冲突
。
控制冲突会使流水线的连续流动受到破坏。当执行条件转移指令时,有两种可能结果:
数据冲突:由于寄存器数据的缺失引发。
而相比之下,控制冲突是由于PC的缺失引发
的,PC值是由条件转移和无条件转移指令控制的。
控制冲突对性能影响更大。 因为,IF在指令流水的第一个阶段。(多周期CPU情况下,对于JUMP,在第二阶段ID上升沿的情况下可以拿到目的地址PC;对于BEQ,在三个阶段EXE两个源操作数做减法,那这个数去选择地址,才能拿到正确的PC值)
如上,所有指令都要在IF阶段使用PC;对于转移指令,至少要到EXE阶段才能得到正确的PC。需要暂停流水线一个或者两个周期。
暂停流水线:
预测分支不成功:
(赌他不会转移)
(赌错了,转移了)
预测分支成功(赌他会转移)
:
(这个其实比较难办)
动态预测:
编译器处理:
用空操作指令loop,防止转移指令后出现控制冲突
控制冲突简单解决方法:一旦发现分支指令就暂停流水线,即暂停该指令之后的所有指令,直到分支指令达到MEM段确定了新的PC值为止。
暂停几个周期,可以根据操作码知道。
减少流水线处理分支指令时暂停周期数的方案:
尽早判断出分支转移是否成功
;尽早计算出分支成功转移时的PC值
(如分支的目标地址)。可能对于上表的情况,将 EX 提前到 ID 时进行,可以减少一个时钟周期的暂停。
如上,从流水线上来看,计算转移的目的地址放在EXE阶段,判断是否能成功转移,也是放在EXE阶段。
对于计算转移的目的地址
是有可能提前的。其所需计算值在上一阶段前就出现。但是判断是否能成功转移
搬不到前面去。再加一个 ALU 是个办法,但是成本有些高。
对于 BEQ 这条指令,可以做个简单的异或,来进行判断。因此对于 BEQ 加一个异或门。
硬件在ID阶段就确定需要的信息,增加:
例子程序 Branch Taken :
36: sub $10, $4, $8
40: beq $1, $3, 7
44: and $12, $2, $5
48: or $13, $2, $6
52: add $14, $4, $2
56: slt $15, $6, $7
...
72: lw $4, 50($7)
上图是 Clock 4 时,写了一个空泡
。
与数据冲突的暂停不同的是:要把旧的指令清楚,写空泡
。
数据通路
控制信号
清除IF/ID段寄存器的值(IF/ID寄存器←NOP)
当前指令的控制信号为0(ID/EX寄存器←0)
r1 与 r2 还有数据冲突怎么办?数据旁路需要大家自己思考。
其实上述过程中已经做了预测(已经预测了分支转移不成功
)。
减少流水线分支开销的方法:
分支目标缓冲技术(Branch Target Buffer)
将分支转移成功的分支指令的地址和它的分支目标地址都放到一个缓冲区中保存起来
,缓冲区以分支指令的地址作为标志;在取指令阶段,所有的指令地址都与保存的标志作比较,如果相同,就认为本条指令是分支指令,而且认为它分支转移成功,同时它的分支目标(下一条指令)地址就是保存在缓冲区中的分支目标地址。
增加分支目的地址存储(Branch Target Buffer)。
首次遇到新的PC,保存它的下一条指令的地址:
Pc+4 alu/lw/sw
Pc+offset BEQ/J
?? JR
机理(这种预测方法为什么能起作用):程序的局部性
。
增加1位BHT位,实现动态预测:BHT: Branch history table
。
LI R1 1
LI R2 1
LI R3 40
SLL R3 R3 0
LI R4 9
SW R3 R1 0
SW R3 R2 1
ADDU R1 R2 R1
ADDU R1 R2 R2
ADDIU R3 2
ADDIU R4 FF
BNEZ R4 F9
静态预测:
动态预测:
无论分支转移成功与否,延迟槽内的指令都要执行。如果分支转移失败,只需要按取来的指令执行;否则,按照分支目标地址的指令执行。
选择放到分支延迟槽中的指令必须按照一定的原则经过编译器的调度。对分支延迟的三种调度方法:
什么是异常?
中断程序正常执行流程的事件:
CPU
,称为异常
外部设备
,称为中断
很难在程序中进行处理
对程序“透明”处理
发现异常:
保存现场
转异常处理程序(中断服务)
处理完成后,返回主程序执行。
把前面的指令正常执行完,把后面的指令变成空操作。把写寄存器、写存储等都清空,改成0。
把新PC值赋给PC(根据中断的原因)。
处理要求:
硬件:
大家可以去查 MIPS CP0 的手册,实现之,来完成异常的处理。
精确异常处理:
非精确异常处理:
冲突问题及解决方案:
控制冲突:
异常: