异常和中断机制
有关异常和中断的基本概念:
由CPU内部产生的意外事件被称为异常,有些教材中也称为内中断;由来自CPU外部的设备向CPU发出的中断请求,被称为中断,通常用于信息的输入与输出。有些教材中也称为外中断。
通常情况下,对异常和中断的具体处理过程,由操作系统(和驱动程序)完成。
异常
异常是由CPU内部产生的意外事件,分为硬故障中断和程序性异常。
- 硬故障中断是由硬连线出现异常引起的,如存储器校验错,总线错误等。
- 程序性异常,也称软件中断,是指在CPU内部因执行指令而引起的异常事件,如整除0、溢出、断点、单步跟踪、非法指令、栈溢出、地址越界、缺页等,按异常发生的原因和返回方式的不同,又可分为故障、自陷和终止。
- 故障:指在引起故障的指令启动后,执行结束前被检测到异常事件。例如指令译码中发现的“非法操作码”,取数据时发生“缺段”或“缺页”,执行除法时除数为0等。对于缺段,缺页等异常事件,经处理后可将所需的段或页面从磁盘调入主存,回到发生故障的指令继续执行,断点为当前发生故障的指令。对于非法操作码、除数为零等,因为无法通过异常处理程序恢复故障,因此不能回到原断点执行,必须终止进程的执行。
- 自陷:是预先安排的一种“异常”事件,就像预先设定的陷阱一样。CPU在执行完自陷指令后,自动根据不同陷阱类型进行相应的处理,然后返回到自陷指令的下一条指令执行。注意当自限指令是转移指令时,并不是返回到下一条指令执行,而是返回到转移目标指令执行。
- 终止:不是由特定指令产生的,而是随机发生的,像是控制器出错、存储器校验错误等等。终止指令和外中断属于硬件中断。
中断
中断可分为可屏蔽中断和不可屏蔽中断。
CPU每执行完一条指令就检查中断请求信号线,如果检测到中断请求,则进入中断响应周期。
也就是说,中断请求检测 由CPU在每条指令执行结束,取下条指令之前进行。
异常和中断的区别
异常和中断的处理过程基本是相同的,本质上是一样的,但它们之间有以下两个重要的不同点:
- 缺页或溢出等异常事件是由特定指令在执行过程中产生的,而中断不和任何指令相关联,也不阻止任何指令的完成。
- 异常的检测由CPU自身完成,不必通过外部的某个信号通知CPU。对于中断,CPU必须通过中断请求线获得中断源的信息,才能知道哪个设备发生了何种中断。
异常和中断的响应过程
CPU,对异常和中断响应的过程,可分为关中断、保存断点和程序状态、识别异常和中断并转到相应的处理程序。
关于识别异常和中断并转到相应的处理程序:异常和中断的识别有软件识别和硬件识别两种方式。异常和中断源的识别方式不同,异常大多采用软件识别方式,而中断可以采用软件识别方式或硬件识别方式。
啥叫软件识别方式:指CPU设置一个异常状态寄存器,用于记录异常原因,操作系统使用统一的异常或中断查询程序,按优先级顺序查询异常状态寄存器,以检测异常和中断类型,先查询到的先被处理,然后转到内核中相应的处理程序。
啥叫硬件识别方式:硬件识别方式又称向量中断异常或中断处理程序的首地址称为中断向量,所有中断向量都存放在中断向量表中。每个异常或中断都被指定为一个中断类型号。在中断向量表中,类型号和中断向量一一对应,因此可以根据类型号快速找到对应的处理程序。
整个响应过程是不可被打断的。
中断响应过程结束后会发生什么?
中断响应过程结束后,CPU就从PC中取出中断服务程序的第一条指令开始执行,直至中断返回。这部分任务是由CPU通过执行中断服务程序完成的,整个中断处理过程是由软硬件协同实现的。
指令流水线
回顾一下一些考试时经常冒出来让人稀里糊涂的词:单周期CPU,多周期CPU。
单周期CPU:一个时钟周期完成一条指令,如果一个程序有多条指令,则时钟周期的时间根据执行时间最长的那条指令为主。执行一条指令就需要一个时钟周期则CPI为1。
多周期CPU:一条指令被分成了若干个阶段,假设为n个,每执行一条指令需要花费n个时钟周期,所以执行一条指令就需要n个时钟周期CPI为n。
关于并行性
目的:提高功能部件的并行性和程序的执行效率。
- 时间上的并行技术:将一个任务分解为几个不同的子任务,每个阶段在不同的功能部件上并行执行,以便在同一时刻能够同时执行多个任务,进而提升系统性能。这种方法被称为流水线技术。
- 空间上的并行技术:在一个处理器内设置多个执行相同任务的功能部件,并让这些功能部件并行工作,这样的处理机被称为超标量处理机。
指令流水线执行的阶段(以五个阶段为例)
- 取址:从指令存储器或Cache中取指令。
- 译码/读寄存器:操作控制器对指令进行译码,同时从寄存器堆中取操作数。
- 执行/计算地址:执行运算操作或计算地址。
- 访存:对存储器进行读写操作。
- 写回:将指令执行结果写回寄存器堆。
理想情况下,每个时钟周期都有一条指令进入流水线,每个时钟周期都有一条指令完成,每条指令的时钟周期数(即CPI)都为1。
流水线设计的原则
指令流水段个数以最复杂指令所用的功能段个数为准,流水段的长度以最复杂的操作所花的时间为准。
由此可见,流水线方式并不能缩短单条指令的执行时间,但对于整个程序来说,执行效率得到了大幅增高。
为了利于实现指令流水线,指令集应具有如下特征:
- 指令长度应尽量一致。
- 指令格式应尽量规整。
- 采用Load/Store指令:其他指令都不能访问存储器,这样可以把load/store指令的地址计算和运算指令的执行步骤规整在同一周期内,有利于减少操作步骤。
- 数据和指令在存储器中对齐存放,有利于减少访存次数,使所需数据在一个流水段内就能从存储器中得到。
单周期CPU的时钟频率取决于数据通路中的关键路径(最长路径),因此单周期CPU指令执行效率不佳。
流水寄存器用于锁存本段处理完成的数据和控制信号,以保证本段的执行结果能在下个时钟周期给下一流水段使用。
每个流水寄存器中保存的信息包括
- 后面流水段需要用到的所有数据信息,包括PC+4指令、立即数、目的寄存器、ALU运算结果、标志信息等,它们是前面阶段在数据通路中执行的结果。
- 前面传递过来的后面各流水段要用到的所有控制信号。
流水线的冒险与处理
根据导致冒险的原因不同,主要有三种:结构冒险(资源冲突)、数据冒险(数据冲突)和控制冒险(控制冲突)。
1.结构冒险
由于多条指令在同一时刻争用同一资源而形成的冲突,也称为资源冲突,即由硬件资源竞争造成的冲突,有以下两种解决办法:
- 前一指令缓存时,使后一条相关指令(以及其后续指令)暂停一个时钟周期。
- 单独设置数据存储器和指令存储器,使取数和取指令操作各自在不同的存储器中进行。
2.数据冒险
在一个程序中,下一条指令会用到当前指令计算出的结果。此时,这两条指令发生数据冲突,数据冒险可分为三类:写后读RAW,读后写WAR,写后写WAW。
以写后读Read After Write相关为例:当前指令将数据写入寄存器后,下一条指令才能从该寄存器读取数据,否则先读后写,读到的就是错误的旧数据。
流水线按序流动时,在RAW、WAW、WAR中,只可能出现RAW相关。
解决方法:
- 把遇到数据相关的指令及其后续指令都暂停一至几个时钟周期,直到数据相关问题消失后再继续执行,可分为硬件阻塞和软件插入NOP指令两种方法。
- 设置相关专用通路,数据旁路技术。
- 调整指令顺序。
3.控制冒险
遇到改变指令执行顺序的情况,例如执行转移调用或返回等,指令时会改变PC值,会造成断流,从而引起控制冒险,解决的方法有以下几种:
- 对转移指令进行分支预测。
- 预取转移成功和不成功两个控制流方向上的目标指令。
- 加快和提前形成条件码。
- 提高转移方向的猜准率。
流水线的性能指标
1.流水线的吞吐率
单位时间内流水线所完成的任务数量,或输出结果的数量。
连续输入的任务数n→∞时,得最大吞吐率为1/Δt。(Δt为时钟周期)
2.流水线的加速比
完成同样一批任务,不使用流水线与使用流水线所用时间之比。
连续输入的任务数n→∞时,得最大加速比为k。(k段流水线)
高级流水线技术
动态流水线是指在同一时间内,当某些段正在实行某种运算时,另一些段却正在进行另一种运算,这样对提高流水线的效率很有好处,但会使流水线控制变得很复杂。
动态流水线是相对于静态流水线而言的,静态流水线上下段连接方式固定,而动态流水线的连接方式是可变的。
有两种增加指令集并行的策略,一种是多发射技术,它通过采用多个内部功能部件,使流水线功能段能同时处理多条指令,处理机一次可以发射多条指令进入流水线执行。另一种是超流水线技术,它通过增加流水线级数来使更多的指令同时在流水线中重叠执行。
- 超标量流水线技术,也称动态多发射技术,每个时钟周期内可并发多条独立指令,以并行操作方式将两条或多条指令编译并执行,为此需配置多个功能部件。
- 超长指令字技术,也称静态多发射技术,由编译程序挖掘出指令间潜在的并行性,将多条能并行操作的指令组合成一条具有多个操作码字段的超长指令字(可达几百位),为此需要采用多个处理部件。
- 超流水线技术是通过提高流水线主频的方式来提升流水线性能的。超流水线技术相当于将流水线再分段,从而提高每个周期内功能部件的使用次数。
超流水线CPU在流水线充满后,每个时钟周期还是执行一条指令,CPI=1,但其主频更高。多发射流水线CPU每个时钟周期可以处理多条指令,CPI<1。相对而言,多发射流水线成本更高,控制更复杂。
补充
关于指令流水线数据通路
数据在功能部件之间传送的路径被称为数据通路,包括数据通路上流经的部件,如程序计数器、ALU、通用寄存器、状态寄存器、异常和中断处理逻辑等。数据通路由控制部件控制,控制部件根据每条指令功能的不同生成对数据通路的控制信号,因此数据通路本身是不包括控制部件的。
给出四个处理器类型(单周期CPU、多周期CPU、基本流水线CPU、超标量流水线CPU),理想情况下,CPI为1的是:单周期CPU、基本流水线CPU。
CPI,表示执行指令所需的时钟周期数,对于一个程序或一台机器来说,其CPI是指执行该程序或机器指令集中的所有指令所需的平均时钟周期数。
对于单周期CPU,令指令周期等于时钟周期,则CPI=1。
对于多周期CPU,CPU的执行过程分成几个阶段,每个阶段用一个时钟去完成,每种指令所用的时钟数可以不同,CPI大于一。
对于基本流水线CPU,让每个时钟周期流出一条指令,CPI=1。
超标量流水线CPU,在每个时钟周期内并发执行多条独立的指令,每个时钟周期流出多条指令,CPI小于一。