《计算机组成原理》知识点---第12章 CPU结构和功能
目录
12.4.3.1 资源冒险(resource hazard)
12.1 CPU组成
CPU需完成的任务:
- 取指令:CPU必须从存储器(寄存器、cache、主存)读取指令。
- 解释指令:必须对指令进行译码,以确定所要求的动作。
- 取数据:指令的执行可能要求对数据完成某些算术或逻辑运算。
- 处理数据:指令的执行可能要求对数据完成某些算术或逻辑运算。
- 写数据:执行的结果可能要求写数据到存储器或I/O模块。
12.2 寄存器组成
CPU中的寄存器可分为两类:用户可见寄存器(user-visible register)和控制和状态寄存器(control and status register)。
12.2.1 用户可见寄存器
用户可见寄存器可分为:通用、数据、地址、条件码。
- 通用寄存器(general-purpose register):可被程序员指派各种用途。任何通用寄存器能为任何操作码容纳操作数。在某些情况下,通用寄存器可用作寻址功能。
- 数据寄存器(data register):仅可用于保持数据而不能用于操作数地址的计算。
- 地址寄存器(address register):可以是自身某些通用性,或是专用于某种具体的寻址方式。例如:段指针(segment pointer)、变址寄存器(index register)、栈指针(stack pointer)。
- 标志寄存器(flag register)
12.2.2 控制和状态寄存器
1. 对于指令执行,有4种寄存器是至关重要的:程序计数器(PC)、指令寄存器(IR)、存储器地址寄存器(MAR)、存储器缓冲寄存器(MBR)。
- 程序计数器(PC):存有待取指令的地址。通常,在每次取指令之后,PC的内容即被CPU更改,故它总是指向将被执行的下一条指令。
- 指令寄存器(IR):存有最近取来的指令。在IR分析操作码和操作数指定符。
- 存储器地址寄存器(MAR):存有存储器位置的地址。
- 存储器缓冲寄存器(MBR):存有将被写入存储器的数据字或最近从存储器读出的字。
▲① 与存储器的数据交换使用MAR和MBR。在总线组织的系统中,MAR直接与地址总线相连,MBR直接与数据总线相连,然后用户可见寄存器再与MBR交换数据。
② ALU可对MBR和用户可见寄存器直接存取。
2. 很多CPU设计都包括常称为程序状态字(program status word,PSW)的一个或一组寄存器。通常PSW包括下列字段或标志:
- 符号(sign):容纳最后算数运算结果的符号位。
- 零(zero):当结果是0时被置位。
- 进位(carry):若操作导致最高位有向上的进位(加法)或借位(减法)时被置位。用于多字算术运算。
- 等于(equal):若逻辑比较的结果相等,则置位。
- 溢出(overflow):用于指示算术溢出。
- 中断允许/禁止用于允许或禁止中断。
- 监管(supervisor):指出CPU是执行在监管模式中还是在用户模式中。某些特权的指令只能在监管模式中执行,某些存储区域也只能在监管模式中被访问。
12.3 指令周期
指令周期包括如下子周期:
- 取指(fetch):将下一条指令由存储器读入CPU。
- 执行(execute):解释操作码并完成指定的操作。
- 中断(interrupt):若中断是允许的并且有中断发生发生,则保存当前进程的状态并为此中断服务
12.3.1 间接周期
可把间接地址的读取看成是一个额外的指令子周期,其过程如下图所示。动作的主线由交替的取指令和指令执行动作组成。取来一条指令后,要对它进行检查以确定是否需要间接寻址。如果是,则所要求的操作数使用间接寻址方式取来。在执行之后,可能有一个中断在取下一条指令之前被处理。
指令周期状态图如下。一旦取来一条指令,它的操作数指定符必须被识别。然后读取存储器中的每个操作数,这个过程可能要求间接寻址。寄存器操作数不需要从存储器读取。一旦操作被执行,可能需要一个类似的过程将结果存入主存。
12.3.2 数据流
12.3.2.1 数据流与取指周期
开始时,PC存有待取的下一条指令的地址。这个地址被传送到MAR并放到地址总线上。控制器发出一个存储器读的请求,存储器把结果放到数据总线上,CPU将其复制到MBR,然后传送到IR。在此期间,PC增1,为下次取指令做好准备。
12.3.2.2 数据流与间接周期
一旦经历过取指周期,控制器检查IR的内容,以确定是否有一个使用间接寻址操作数的指定符。若是,则进入间接周期。MBR最右边的N位是一个地址引用,被传送到MAR。然后,控制器请求一个存储器读,得到所要求的操作数地址,并送入MBR。
12.3.2.3 数据流与中断周期
PC中的当前内容必须被保存,以便在中断之后CPU能恢复先前的动作。于是,PC的内容被传送到MBR,将被写入存储器。为此目的,一个专门的存储器位置被控制器装入MAR。它可能是一个栈指针。随后,中断子程序的地址装入PC。结果是,下一指令周期将以取此相应的指令而开始。
取指、间接、中断周期都是简单的并且可预期的。
12.4 指令流水线技术
12.4.1 流水线策略
考虑指令处理的如下分解:
- 取指令(FI):读下一条预期的指令到缓冲器。
- 译码指令(DI):确定操纵码和操作数指定符。
- 计算操作数(CO):计算每个源操作数的有效地址,这可能涉及偏移寻址、寄存器间接寻址、间接寻址或其他形式的地址计算。
- 取操作数(FO):从存储器取出每个操作数。寄存器中的操作数不需要取。
- 执行指令(EI):完成指定的操作。若有指定的目的操作数的位置,则将结果写入此位置。
- 写操作数(WO):将结果存入存储器。
下图表示了一个这样的6段流水线,能将9条指令的执行时间由54个时间单位减少到14个时间单位。
图12-11说明了条件转移的影响,其中使用与图12-10同样的程序。假定,指令3是一个可能转到指令15的条件转移指令。
12.4.2 流水线性能
指令流水线的周期时间T,是在流水线中将一组指令推进一段所需的时间,时间周期可表示成:
现假设n条指令在进行,无转移发生。令Tk,n为k阶段流水线执行所有n条指令所需的总时间,则有
使用指令流水线相对于不使用流水线的加速比定义为:
12.4.3 流水线冒险
有三种类型的流水线冒险:资源冒险、数据冒险和控制冒险。
12.4.3.1 资源冒险(resource hazard)
发生在两条(或多条)已进入已进入流水线的指令需要使用相同资源的时候。结果就是在流水线某个部分,这些指令必须串行执行,而不是并行执行。资源冒险在有些时候也称为结构冒险。
例子如下:
12.4.3.2 数据冒险(data hazard)
发生在对一个操作数位置的访问出现冲突的时候。通常可以用如下形式来描述数据冒险:程序中的两条指令依次执行,并且都将访问同一个内存或寄存器操作数。如果两条指令的执行是严格串行的,那么没有问题发生。但是,如果这两条指令在流水线中运行,那么有可能操作数会不按次序更新,从而导致与严格串行执行不一样的结果。
例子如下:
有3种类型的数据冒险:
- 写后读(Read After Write,RAW)或真相关(true dependency):一条指令改写一个寄存器或内存位置,而后续的指令从所改写的寄存器或内存位置读取数据。如果在写操作完成之前,读操作就开始进行,那么就会发生冒险。
- 读后写(Write After Read,WAR)或反相关(anti-dependency):一条指令读一个寄存器或内存位置,而后续的指令将改写该寄存器或内存位置的内容。如果在读操作完成之前,写操作就开始进行,那么会发生冒险。
- 写后写(Write After Write,WAW)或输出相关(output dependency):两条指令要改写同一个寄存器或内存位置。如果这两条指令的写操作发生次序与期望的次序相反,那么就会发生冒险。
12.4.3.3 控制冒险(control hazard)
又称分支冒险,发生在流水线对分支转移做出了错误的预测,因此读取了在后期必须取消的指令之时。
12.4.4 处理分支指令
已有几种方法用于处理条件分支指令:
- 多个指令流(multiple streams)
- 预取分支目标(prefetch branch target)
- 循环缓冲器(loop buffer)
- 分支预测(branch prediction)
- 延迟分支(delayed branch)
1. 多个指令流
复制流水线的开始部分,并允许流水线同时取这两条指令,使用两个指令流。这种方法有两个问题:
①使用多个流水线,会有寄存器和存储器访问的竞争延迟。
②在原先的分支判断还没解决之前,可能又有另外的分支指令进入流水线(不管哪一路)。这样又需要添加指令流。
2. 预取分支目标
识别出一个条件分支指令时,除了取此分支指令之后的指令外,分支目标处的指令也被取来。这个目标保存直到分支指令被执行。若是分支发生,则目标已经被预取来了。
3. 缓冲寄存器
缓冲寄存器是由流水线指令取指阶段维护的一个小的但极高速的存储器,含有n条最近顺序取来的指令。若一个转移将要发生,硬件首先检查转移目标是否在此缓冲器种。若是,则下一条指令由此缓冲器取得。
4. 分支预测
- 预测绝不发生(predict never taken)
- 预测总是发生(predict always taken)
- 依操作码预测(predict by opcode)
- 发生/不发生切换(taken/not taken switch)
- 转移历史表(branch history table)
前三种方法是静态的,它们不取决于条件转移指令的过去执行历史。后两种方法是动态的,它们取决于执行的历史。
5. 延迟分支