流水线中的异常
异常的来源
- 外部事件
- 指令执行中的错误
- 数据完整性的问题
- 地址转换异常
- 系统调用
- 陷入
- 需要软件修正的运算
异常可以分为:可恢复异常和不可恢复异常
不可恢复异常:系统硬件出现严重故障,异常处理后系统面临重启。
解决办法:立即终止当前的执行,记录软件所需的信息然后跳转到异常的处理入口。
可恢复异常:又称为精确异常,要求处理完异常后,回到产生异常的地方继续执行,还能执行正确,就像没发生过异常一样。
解决办法:要求在处理异常时,发生异常指令的前面的所有指令都执行完,而发生异常的指令及其后面的指令都没有执行。
书上给出的一种可行的实现精确异常的方案:
提高流水线效率的技术
执行时间
执行时间是用来衡量一款处理器性能的手段。
执行时间=指令数每条指令执行周期数(CPI) *时钟周期
流水线处理器实际的CPI等于指令的理想执行周期数+由于指令相关引起的阻塞周期数
CPI=CPI+RAW+WAR+WAW
多发射数据通路
让处理器中每级流水线都可以同时处理更多的指令
双发射流水线:每一拍用PC从指令存储器中取两条
指令,在译码级同时进行两条指令的译码、读源寄存器操作,并且同时执行两条指令的运算操作和访存操作,并同时写回两条指令的结果。双发射的理想CPI从单发射的1降为0.5。
双发射处理器流水线
双发射处理器流水线的时空图:
注:当同一个时钟周期执行的两条指令存在指令相关时,也需要进行阻塞。
动态调度
基本思想:把相关的解决尽量往后拖延,同时前面的指令的等待不影响后面指令继续前进。
假设有一个双发射流水线,执行以下指令:
div.w $r3,$r2,$r1
add.w $r5,$r4,$r3
sub.w $r8,$r7,$r6
【分析】除法指令div是需要多个执行周期的,加法指令add和div是RAW相关的,所以最早
要等到div执行完之后才能执行。但是减法指令sub和上两条指令是无关的。所以可以在执行除法指令的同时执行减法指令。动态调度的解决办法就是允许减法指令越过前面尚未执行完毕的除法指令和加法指令,提前开始执行
sub指令是在流水线由于指令间的相关引起阻塞而空闲的情况下,见缝插针地提前执行。
如何改进流水线
- 将译码阶段拆成:译码+读操作数两个阶段
- 等待的指令:译码阶段检查结构相关,读操作数阶段一直等待直至操作数可以读取。在等待状态的指令不能一直停留在原有的译码流水线上,这样它后面的指令没法前进或是进入流水线。
- 保留站:一个存储等待指令的结构,也称为发射队列
除了存储指令,保留站还要控制其中的指令何时去执行,因此保留站中还会记录下,描述指令间相关关系的信息,监测各条指令的执行状态。如果指令时在进入保留站前读取寄存器,那么保留站还需要监听每条结果总线,获取源操作数的最新值
保留站通常是一个无序队列
,每一项对应一条指令,包含多个域,存放该指令的监听结果
和后续执行所需的各类信息
(见上图)。
译码并读寄存器的指令进入保留站,保留站会每个时钟周期选择一条没有被阻塞的指令,送往执行逻辑,并退出保留站,这个动作称为发射
。
关于保留站如何处理数据相关引起的阻塞以及结构相关和控制相关的起因以及如何解决下一篇再讲。