本次笔记内容:
P25 计算机组成原理(25)
P26 计算机组成原理(26)
本节课对应幻灯片:
每一条指令的实现至多需要5个时钟周期。这5个时钟周期如下:
不同类型的指令在以上5个时钟周期中进行的操作各不相同。
我们希望CPU在每个时钟周期中,都能完成一条指令,并且开启一条指令。
每一个时钟周期启动一条新的指令,就可以使数据通路成功流水,每一个时钟周期就是流水线的一个流水段。每一条指令经过5个时钟周期执行完成,而在每一个时钟周期内,硬件将启动一条新的指令并执行5条不同指令的某个部分。
在流水线的各个流水段之间加入了被称为流水线寄存器(流水线锁存器)的寄存器堆,并在这些寄存器堆上标明所连接的流水段。
数据
和控制信号
。PC值多路选择器被移到IF段,这样做的目的是保证对PC值的写操作只出现在一个流水段内,否则当分支转移成功的时候,流水线中两条指令都试图在不同的流水段修改PC值,从而发生写冲突。
每个时刻,每条指令都只在一个流水段上是活动的,因此,任何指令所作的任何动作都发生在一对流水线寄存器之间。
因此,增加阶段寄存器。不算 pc 的话,共四个。如下。
所有的控制信号
控制信号:MEM及WB
WB阶段控制信号
实际的流水线就这么简单吗?——NO!
流水线资源冲突
问题,即要保证流水线的各段在同一个时钟周期内
不会使用相同的数据通路资源
。简化的流水线数据通路:
很少
。
如上,对于CC4这个时间,第一个指令要去寄存器写数据;但是第四个指令,其要去取址,要把去寄存器把数据取出来。
什么是流水线中的“冲突”?
流水线中的冲突
结构冲突
,是指令在重叠执行的过程中,硬件资源满足不了指令重叠执行的要求,发生硬件资源冲突而产生的冲突。数据冲突
,是指在同时重叠执行的几条指令中,一条指令依赖于前面指令执行结果数据,但是又得不到时发生的冲突。控制冲突
,它是指流水线中的分支指令或者其他需要改写PC的指令造成的冲突。解决流水线中“冲突”问题的重要性
问题: 两条或者多条在流水线中的指令去访问相同的物理资源。
解决方法:
可以增加更多的硬件资源来解决结构冲突。
在实际操作中,CPU放在高速缓存Cache中,在Cache中指令与数据是地址分开的。
对于每一条指令来说:
设置不同的“端口”来避免结构冲突:
在一个时钟周期同时完成三次访问。
两个可选的解决方案:
在相同的时钟内同时完成对于寄存器的读写是可以的。
内存物理结构的限制:
流水线处理器可以通过暂停流水线的办法来解决,对于每一次取指在出现内存结构冲突的时候需要等待一个时钟周期(流水线中的气泡)。
另外的解决办法:将指令内存和数据内存分开,这样取指和数据内存访问不会发生结构冲突。
Caches: small and fast “buffer” memories,哈佛结构,通常使用在L1缓存中。
如果因资源冲突而无法使用某种指令组合,那么就称流水线产生了结构冲突。
消除结构冲突的最简单方法就是引入暂停周期,这必然要降低流水线的性能。如下。
解决结构冲突的基本方法:结构冲突的起因是资源争用,那么可以考虑采用资源充分重复设置的方法来避免结构冲突。
解决存储器争用冲突的办法:
取指令和访问数据可以并行进行,不会发生结构冲突。
流水线技术可以通过指令的重叠执行来改变指令的相对执行时间,这就可能导致流水线中的指令序列读写操作数的顺序发生改变,而不同于非流水线时的指令序列读写操作数的顺序。
按照指令读写寄存器顺序对数据冲突分类:对于两条指令i和j,假设指令i在j之前进入流水线,下面讨论几种不同的数据冲突。
写后读冲突(RAW:Read After Write)
写后写冲突(WAW:Write After Write)
MIPS指令流水不会发生WAW冲突
读后写冲突(WAR:Write After Read)
MIPS指令流水中不会发生WAR冲突
结果可用的时候即可前传,无需先保存到RegFile。
使用前传部件传输数据,Pictured: ALU → ALU in one and 2 cycles。
数据冲突的类型:
EXE段数据冲突的检测
EXE冲突检测点:当前指令的ID/EX段和上一指令的EX/MEM段
EX/MEM.RegWrite AND EX/MEM.RegisterRd != 0 AND EX/MEM.RegisterRd = ID/EX.RegisterReadRs (Rt)
MEM段数据冲突的检测
与EXE段基本类似,略有不同。
如上图,增加了一个 Forwarding Unit ,把数据冲突信息传送到多路检测器。
检测条件:
ID/EX.MemRead AND (ID/EX.RegisterRt= IF/ID.RegisterRs OR ID/EX.RegisterRt= IF/ID.RegisterRt)
则需要暂停流水线。
一旦发生此类冲突,暂停流水线一个时钟:
并且,将LW指令的结果通过旁路送到ALU输入端,Forwarding逻辑需要增加什么呢?(作为思考题,是否需要增加呢?)
在数据装入之后的那个周期被称为是 load delay slot
。
一些硬件的实现:
另一个解决办法: 让汇编器assemble或者程序员放一条不相关的指令,避免冲突 → 无需暂停!
代码顺序调换来避免流水线暂停 Assembler Update!
通过汇编器避免下一条指令结果依赖装入指令!(汇编器调度,静态调度)
数据冲突的动态调度:
执行顺序
以减少暂停的影响,能够简化编译器设计。指令顺序发射——乱序执行——指令乱序流出
结构冲突
数据冲突