参考:计算机组成原理教材
一、基础概念
1)触发器和锁存器
触发器是能存储1bit信号的基本单元电路。
锁存器就是多位触发器,因为触发器只能存储1bit,而一般参与运算的操作数都是多bit的,所以引入了锁存器。锁存器经常被用作CPU的运算器中的数据暂存器。以后看到锁存器就把它想象成一个临时存放数据的地方。
2)组合逻辑电路和时序逻辑电路
组合逻辑电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关,也就是说组合逻辑电路没有"记忆",运算后的结果要立即送入寄存器保存
时序逻辑电路在逻辑功能上的特点是任意时刻的输出不仅取决于当时的输入信号,还取决于电路原来的状态。也就是说时序逻辑电路有记忆原件,即触发器,可以记录前一时刻的输出状态(CPU从整体上就是一种复杂的时序逻辑电路)
3)CPU的速度影响因素
现代计算机都采用流水线的方式执行指令,使得每条指令大多能在一个时钟周期内完成,这样看主频越高,CPU的运算速度就越快了。实际上机器的速度不仅与主频有关,还与机器周期中所含的时钟周期数以及指令周期中所含的机器周期数有关,同样主频的机器,机器周期所含时钟周期数越少的机器速度更快。
4)数据通路带宽
数据总线一次所能并行传送信息的位数。
5)一些性能指标
吞吐量
指系统单位时间内处理请求的数量。它取决于信息能多快地输入内存,CPU能多快地取指令,数据能多快地从内存取出或存入,以及所得结果能多快地从内存送给一台设部设备。这些步骤中的每一步都关系到主存,因此,系统吞吐量主要取决于主存的存取周期。
响应时间
指从用户向计算机发送一个请求,到系统对该请求做出响应并获得它所需要的结果的等待时间。通常包括CPU时间(运行一个程序所花费的时间)与等待时间(用于磁盘访问、存储器访问、IO操作、操作系统开销等时间)。
主频
机器内部主时钟频率,其倒数为CPU时钟周期(一个指令周期由若干机器周期(CPU周期)组成,每个机器周期由若干时钟周期组成)
运算速度
CPI(Clock Cycle Per Instruction):执行一条指令所需要的时钟周期数
IPS(Istructions Per Second):每秒执行多少指令
MIPS(Million Instruction Per Second):每秒可执行多少个"百万条指令"
MFLOPS(Mega Floating-point Operations Per Second):每秒执行多少百万次浮点运算
GFLOPS(Giga Floating-point Operations Per Second):每秒执行多少十亿次浮点运算
TFLOPS(Tera Floating-point Operations Per Second):每秒执行多少万亿次浮点运算
PFLOPS(Peta Floating-point Operations Per Second):每秒执行多少千万亿次浮点运算
6)微操作和微命令
一条机器指令可以分解成一个微操作序列,这些微操作是计算机中最基本的、不可再分解的操作。
将控制部件向执行部件发出的各种控制命令称为微命令,它是构成控制序列的最小单位。微命令和微操作是一一对应的,微命令是微操作的控制信号,微操作是微命令的执行过程。
7)微指令周期
读出微指令的时间加上执行该条微指令的时间。注意:微指令周期常取成和机器周期相等
8)机器周期和指令周期
机器周期:又称CPU周期或基本周期,在计算机中为了便于管理,常把一条指令的执行分为若干阶段,每个阶段完成一项基本工作,完成一项基本工作所需要的时间就是一个机器周期,每个机器周期的时长可能不等,各自由若干个时钟周期组成。
指令周期:通常由若干个机器周期组成,每个机器周期可能不同。
比如在间接寻址时需要多访问一次存储器取出有效地址,故带有间址周期的指令周期 =取指机器周期+间址机器周期+执行机器周期。
再比如当CPU采用中断方式实现主存与IO信息交换时,CPU在每条指令的执行机器周期结束前都要发出中断查询信号,以检查是否有IO提出请求。如果有请求,则CPU要进入中断响应阶段,又称为中断机器周期。这样一个完整的指令周期 = 取指机器周期+间址机器周期+执行机器周期 + 中断机器周期。
9)指令执行方案
一个指令周期通常要包括几个时间段(执行步骤),每个步骤完成指令的一部分功能,几个依次执行的步骤完成这条指令的全部功能。对于指令来说,有以下三种方案来安排指令的执行步骤。
单指令周期方案
对所有指令都选用相同的执行时间来完成。该方案的每一条指令都在固定的时钟周期内完成,指令之间串行执行,即下一条指令只能在前一条指令执行结束后才能启动。
多指令周期方案
该方案的指令之间仍然串行执行,但是可以选用不同个数的时钟周期来完成不同指令的执行过程,指令需要几个周期就为其分配几个,不在要求所有指令占用相同的执行时间。
流水线方案
指令之间可以并行执行的方案,理想情况(实际上不可能发生)是在从第2条指令开始,每个时钟周期完成一条指令的执行。通过在每一个时钟周期启动一条指令,尽量让多条指令同时运行,但各自处在不同的执行步骤中。对于每条指令来说它还是要经过若干过程才能完成,所以一条指令的执行时间并没有缩短。
比如将一个指令周期分为取指FI、指令译码ID、计算操作数地址CO、取操作数FO、执行指令EI和写操作数WO共6个阶段,就形成6级流水线。当使用6级流水线时执行N条指令,第一条指令仍需要6个时钟周期,从第二条指令开始每条指令需要1个时钟周期,故理想情况所需要的时钟周期就为1 x 6 + (N-1) x 1 = N+5。
10)处理器的度
处理器的度为1就是常规标量单流水线处理器(标量流水线),比如上面提到的6级流水线就是单流水线,每个时钟周期只能只能执行一条指令的某个阶段。 (将一条指令分成若干个时钟周期处理以达到多条指令重叠处理,从而提高cpu部件利用率的技术叫做标量流水技术,这种技术只有一条流水线,每个时钟周期只能执行一条指令的某个阶段。也就是说在单条流水线结构中,指令虽然能够重叠执行,但仍然是顺序/串行的)。
而处理器的度大于1就是常说的超标量流水线,也就是在某一时间可以并发执行多条独立指令
11)超标量流水线
超标量流水线技术每个时钟周期可以并发执行多条独立指令的同一个阶段,也就是说可以有多条独立的流水线。
12)超流水线
在单流水线结构中理想条件下平均每个时钟周期可以完成一条指令。而所谓的超流水线是将机器指令划分为更多级的操作,以减轻每一级的复程度;在流水线的每一步中,如果需要执行的逻辑操作少一些,那么每一步就可以在较短时间内完成。
在一个时钟周期内再细分时间段,一个功能部件使用多次。
13)超长指令字(Very Long Instruction Word,简称VLIW)
由编译程序挖掘出指令潜在的并行性,将多条能并行操作的指令组合成一条具有多个操作码字段的超长指令字(可达几百bit),为此需要采用多个处理部件
14)动态流水线和静态流水线
动态流水线就是多种运算可以同时进行,而静态流水线只能是一种运算进行完再进行下一种运算。
二、CPU(控制器+运算器+片内Cache + 中断系统)的功能和基本原理
CPU的工作过程就是周而复始地执行指令;另外为了使CPU和外部设备能很好协调工作,尽量使CPU不等待,甚至不参与外部设备的输入输出过程,采用了程序中断方式和DMA方式,在这二种方式下,外部设备需要向CPU提出中断请求或DMA请求。
一般在一个机器周期结束时结束时查询是否有DMA请求,如果有,则CPU脱离总线,由DMA控制器控制使用总线。在一个指令周期结束时查询是否有中断请求,如果有,则进入中断响应机器周期,相当于执行了一条中断响应隐指令。在中断响应过程中,得到中断服务程序的入口地址,并送程序计数器PC中,下个指令周期开始时,取出中断服务程序的第一条指令执行。
1)CPU的基本功能
1)指令控制:控制器能自动地形成指令的地址,并能发出取指令的命令,将对应此地址的指令取到控制器中;
2)操作控制:取到指令之后,应该产生完成每条指令所需要的控制命令;
3)时间控制:控制命令产生后需要对各种控制命令加以时间上的控制;
4)数据加工:在执行的过程中,可能需要进行算术运算和逻辑运行
5)中断处理:处理中断
2)运算器(由内部寄存器和VLU组成)
内部寄存器
1)暂存寄存器
暂存从主存读来的数据,这个数据不能放在通用寄存器中,否则会破坏其原有内容。对应用程序员是透明的(透明指的是不能通过程序去访问,反汇编语言也不可见该寄存器)
2)累加寄存器ACC
它是一个通用寄存器,暂时存放ALU运算的结果,至少有一个或多个。
3)通用寄存器组
比如AX/BX/CX/DX/SP等,对程序员可见
4)程序状态字寄存器PSW
是一个由各种状态条件标志(比如中断和系统工作装填信息、运算结果进位标志、运算结果溢出标志等)拼凑而成的寄存器
ALU
是一种组合逻辑电路,因此在实际使用ALU时,其输入端口A和B必须与锁存器相联,而且在运算的过程中锁存器的内容是不变的,其输出也必须送至寄存器保存。
ALU是CPU的执行部件,不仅是执行各种算术(加减乘除)和逻辑运算(与或非异或等),还具有先行进位逻辑。
3)控制器(由内部寄存器和CU二部分组成)
内部寄存器
1)程序计数器PC
存放下一条需要执行的指令,因而程序员可以通过转移指令、调动子程序等指令来改变其内容,故对程序员不透明
2)指令寄存器IR
用来保存当前正在执行的指令。当执行一条指令时,先把它从主存取到存储器数据寄存器MDR中,然后传送至IR。指令划分为操作码和地址码字段,为了准确执行该指令,必须对操作码进行测试来识别所要求的操作。指令译码器就是做这项工作的。IR中操作码字段的输出就是指令译码器的输入。操作码一经译码即可向操作控制器发出具体操作的特定信号。
3)存储器数据寄存器MDR
用来暂时存放从主存读出的一条指令或者一个数据字;反之当向主存存入一条指令或一个数据字时,也暂时将它们存放在MDR中。
4)存储器地址寄存器MAR
用来保存当前CPU所访问的内存单元的地址。由于在内存和CPU之间存在着操作速度上的差别,因此必须使用MAR来保存地址信息,直到内存的读/写操作完成为止。
注意:
如果把外部设备的设备地址作为像内存的地址单元那样来看待,那么当CPU与外部设备交换信息时,同样使用MDR和MAR。
IR、MDR、MAR是CPU的内部工作寄存器,在程序执行的过程中是自动赋值的,程序员无法对其操作,或者称为用户不可见。
CU
CU的外特性
CU的设计/实现方式有微程序控制和硬布线控制二种:
CU的微程序控制方式(CISC处理器一般采用这种方式设计?)
一条机器指令的功能由一段微程序实现(每个微程序由若干条微指令构成,各微指令包含若干条微命令)。所有指令对应的微程序放在只读存储器(这个只读存储器在CPU内部,称为控制存储器CM)中。当执行某条机器指令时,取出对应微程序中的各条微指令,逐条执行即可。这种设计方式简单,指令添加容易、灵活,可维护性好但是速度较慢。
每一条机器指令都与一个以操作性质命名的微程序对应。由于任何一条机器指令的取指令操作都是相同的,所以将取指令周期操作统一编成一个微程序,这个微程序只负责将指令从主存取出并送到IR中。此外如果是间址寻址指令,其操作也是可以预测的,也可以编出对应间址周期的微程序。当出现中断时,中断隐指令所需完成的操作可由一个对应中断周期的微程序完成。也就是说如果机器有M条指令,那么就对应了M+3条微程序。
微程序控制相关概念:
1)微指令和微指令周期
微指令是若干微命令集合。存放微指令的控制存储器CM的单元地址称为微地址。微指令包含二个字段:操作控制字段(又称微操作码字段/微命令字段,用于产生某一步操作所需要的各种操作控制信号)和顺序控制字段(又称微地址字段/下地址字段,用于产生下一条要执行的微指令地址)。
在取指微程序中,除了第一条微指令外(因为执行的第一条微指令地址由专门的硬件电路产生),其余微指令的地址均由上一条微指令的下地址字段直接给出。
微指令周期是从控制存储器中读取一条微指令并执行相应微操作所需的时间,和指令周期类似。
2)控制存储器CM
简称控存,和主存一样用于属于自己的地址寄存器CMAR和数据寄存器CMDR,前者用来存放欲读出的微指令地址,后者用来存放从CM中读出的微指令。
CU的组合逻辑控制方式(RISC处理器一般采用这种方式设计?)
也称硬布线逻辑控制,由基本的门电路组合实现,这种方式实现的CU的处理速度快,但因为每一条微操作命令都对应一个逻辑电路,而且指令系统功能越全,微操作命令就越多,所以一旦设计完毕便会发现这种控制单元的电路结构非常庞杂。
硬布线CU的微操作:CU具有发出各种微操作命令(控制信号)序列的功能。这些命令与指令有关,必须按一定的次序发出。
示例:微操作的节拍和安排设计步骤
每一条机器指令要完成的操作是固定的 ,因此不论是组合逻辑设计还是微程序设计,对应相同的CPU结构,二种CU的微操作命令和节拍安排是极其相似的。
微程序控制单元在取指周期发出的微操作命令如下:
T0: (PC)->MAR, 1->R
T1: M(MAR)->MDR, (PC)+1->PC
T2: (MDR)->IR, OP(IR)->微程序CU的微地址形成部件
与组合逻辑相比,只是在T2节拍内的微操作命令有所不同。微程序控制单元在T2节拍将机器指令的操作码字段送微地址形成部件,以形成对应某条机器指令的微程序首地址。而在组合逻辑控制单元中T2节拍内要将指令的操作码送到硬布线CU的操作码译码器以控制CU发出相应的微命令。即OP(IR)->硬布线CU的操作码译码器
4)中断系统
指令周期被分为取指周期、间址周期、执行周期和中断周期,所以一定是某条执行执行结束后才会去相应中断,中断处理完成后继续执行下一条指令。
当CPU执行完一条现行指令时,如果外部设备向CPU发出中断请求,那么CPU在满足响应条件的情况下。在中断周期中将发出中断响应信号,于此同时关闭/禁止中断表示CPU不再受理另外一个设备的中断;这时CPU将寻找中断中断请求源是哪一个设备,并保存CPU自己的程序计数器PC的内容;然后它将跳转到处理该中断源的中断服务程序。
在中断服务程序里保存CPU现场(被中断的原程序在断点处各个寄存器的值,为防止被改变,需要将这些寄存器值压栈)后开始执行对应的中断处理,处理完成后恢复CPU的现场信息(寄存器值出栈),然后开中断,并返回到原来被中断的主程序的下一条指令。
CPU在什么时条件、什么时候、以什么方式来响应中断
条件:中断允许触发器EINT=1(开中断),且有中断请求时
时候:CPU总是在指令执行周期结束后,去查询是否有中断,如果有则进入中断周期,如果没有则进行下一条指令的取指周期
方式:CPU要响应中断,就必须进入中断周期,一旦进入,即由中断隐指令(硬件自动)完成下列操作
1)保护程序断点:将当前程序计数器PC的内容保存到存储器中,它可以保存在存储器特定单元也可以保存在栈中。
2)寻找中断服务程序入口地址(寻找中断向量)
3)关中断:为避免收到新中断请求的干扰。
CPU响应中断后如何保存现场
保存现场包括程序断点(PC的内容)和CPU内部各寄存器内容的保护。其中程序断点的保护由中断隐指令完成,CPU内部各寄存器内容的保护在中断服务程序中由用户或者操作系统用机器指令编程实现。
中断处理结束后,CPU如何恢复现场,如何返回到原程序间断处
恢复现场是在中断返回前,必须将寄存器的内容恢复到中断处理前的状态,这部分工作也由中断服务程序完成
多重中断(中断嵌套)
当CPU正在执行某个中断服务程序时,另一个中断源又提出了新的中断请求,而CPU又响应了这个新的请求,于是暂停正在运行的中断服务程序,转去执行新的中断服务程序,这称为多重中断,又称为中断嵌套。
多重中断需要满足二大条件
1)由于再次开中断是在中断服务程序结束之后才有的,不然不予响应任何中断,所以需要满足的第一个条件是提前设置"开中断"指令。开中断指令的位置决定了CPU能否实现多重中断,此时用户中断服务程序流程为:保存现场->开中断->设备中断服务->恢复现场->中断返回。
2)在满足1)的前提下,只有优先级别更高的中断请求源,才可以中断比其级别低的中断服务程序,所以比如满足:优先级别高的中断源有权中断优先级别低的中断源。为了保证级别低的中断源不干扰比其级别高的中断源的中断处理过程,可采用屏蔽技术
屏蔽技术
每个中断请求触发器都有一个屏蔽触发器,将所有屏蔽触发器组合在一起,便构成了一个屏蔽寄存器。屏蔽寄存器的内容称为屏蔽字。每个中断源都对应一个屏蔽字。那么什么时候设置屏蔽字合适呢?由于只要中断一开,就允许中断嵌套,因此设置屏蔽字的指令必须安排在中断服务程序的开中断指令之前。
加入中断屏蔽技术的用户中断服务处理流程为:保存现场->置屏蔽字->开中断->设备中断服务->关中断->恢复现场->恢复现场->恢复屏蔽字->开中断->中断返回
中断响应优先级和中断处理优先级
中断响应优先级是指CPU响应各中断源请求的优先级,这种次序往往是硬件电路已经设置好的,不便于改动。
中断处理优先级是指CPU实际对各个中断源请求处理的优先次序,可以通过屏蔽技术来改变处理优先级次序。若不采用屏蔽技术,则中断响应优先级次序就是中断处理优先级次序。
中断优先级与屏蔽字的关系示例:4个中断源1、2、3、4的优先级按降序排列 |
|
优先级 |
屏蔽字 |
1 |
1 1 1 1 |
2 |
0 1 1 1 |
3 |
0 0 1 1 |
4 |
0 0 0 1 |
从上表可以看出优先级3的屏蔽字为0011,表示中断源1和2都是比它优先级高的,换句话说这4bit二机制分别代表4个中断源,第i bit为0时表示第i个中断源不可屏蔽。
中断向量和中断向量地址
中断向量就是中断服务程序的入口地址,而中断向量地址就是中断服务程序的入口地址的地址
禁止中断和屏蔽中断
禁止中断就是关中断,使中断允许触发器置0(EINT=0),此时任何中断请求都得不到响应。
屏蔽中断时多重中断系统的一个概念,是指某个中断正在被处理时,如果有其他新的中断请求产生,是否允许响应新发生的中断。它反应了正在处理的中断和其他各个中断之间的处理优先级顺序,所以每个中断都有一个中断屏蔽字,其中的每一位对应一个中断的屏蔽位,为"1"则对应的中断不能被响应。响应某个中断后,就会把它的中断屏蔽字送到中断屏蔽字寄存器中,在中断排队前,其中的每一位和中断请求寄存器的对应位进行与操作。因而,只有未被屏蔽的中断源进入排队线路,才可能得到响应。
三、CPU的指令集系统
1)CISC和RISC
全部机器指令的集合就构成了一套指令系统,目前有二套指令系统CISC和RISC。
CISC(Complex Instruction Set Computer)既有简单指令,又有复杂指令,后来人们发现典型的程序中80%的语句都是使用计算机中20%的指令,而这20%的指令都是简单指令,剩下的20%语句使用80%的复杂指令。因此既然典型的80%语句都是使用简单指令完成,那剩下的20%语句用简单语句重新组合一下来模拟这些复杂指令的功能就行了,而不需要使用复杂指令来实现,于是RISC(Reduced Instruction Set Computer)出现了。
RISC主要特点
1)选取使用频率较高的一些简单指令以及一些很有用但又不复杂的指令,让复杂指令的功能由使用频率高的简单指令的组合来实现。因此在RISC机器上实现特殊功能时效率可能低,但可以利用流水技术和超标量技术加以改进和弥补;而CISC的指令系统丰富,又专用指令来完成特定的功能,因此处理特殊任务效率高。
2)指令长度固定(因此指令和数据按边界对齐存放),指令数少、指令格式种类少,寻址方式种类少
3)只有Load/Store指令访问存储器,其余指令的操作都是在寄存器内完成
4)CPU中有多个通用寄存器,比CISC多,因此就可以减少访存次数
5)采用流水线技术(RISC一定采用流水线技术),大部分指令在一个时钟周期(主频的倒数,是CPU中最小的时间单位, 这里注意和指令周期和CPU周期(机器周期)的区别)内完成,采用超标量和超流水线技术,可使每条指令的平均执行时间小于一个时钟周期。
6)控制器采用组合逻辑控制,不用微程序控制
7)采用优化的编译程序
CISC主要特点
1)指令系统复杂庞大,指令数目一般多达200-300条
2)指令长度不固定,指令格式种类多,寻址方式种类多
3)可以访存的指令不受限(RISC只有取数/存数指令访问存储器)
4)由于80%的程序使用其20%的指令,因此CISC各指令的使用频率差距太大
5)各种指令执行时间差距很大,大多数指令需要多个时钟周期才能完成
6)控制器大多数采用微程序控制
7)难以用优化编译生成高效的目标代码程序
2)指令的组成
每条机器指令由操作码(定长和不定长二类)和地址码二部分组成,其中地址码可以是操作数本身、操作数地址或者是操作数地址的计算方法。
操作数可以有0个或者多个,也就是说每一条指令都必须包含操作码来告诉CPU该指令做什么操作,比如空操作指令、停机指令、关中断指令等都是只有操作码。另外由于操作数可以在主存、也可以在CPU通用寄存器、因此这里说的地址既可以是主存地址,也可以是寄存器地址、甚至还可以是IO设备地址。
需要注意的是指令的地址码字段往往并不是操作数的真实地址,而是形式地址,这里用A表示,(A)即表示形式地址A所指向的存储介质的数值。用形式地址A结合指令的数据寻址方式可以计算出操作数的真实地址,称为有效地址,用EA表示,(EA)即表示有效地址所指向存储介质的数值,亦即操作数。如果此时EA=(A),表示形式地址A所指向的存储介质中的数值就是操作数的有效地址,而(EA)才是真实的操作数。
补充:指令的字长
一条机器指令所占用存储空间的大小。由于主存一般都是按照字节编制的,因此指令字长一般都是字节的整数倍。如果某机器指令的字长等于机器字长,则称此指令为单字长指令;如果某指令的长度等于机器字长的一半,则称此指令为机器字长的一半,则称此指令为半字长指令;如果等于机器字长的二倍,则称此指令为双字长指令。
指令字长取决于操作码的长度、操作数地址的长度(比如取决于主存大小,如果容量为1GB的主存按字节寻址,每个操作数地址的长度都要30bit的地址码)以及操作数地址个数。
3)指令的寻址方式
指令或者操作数有效地址的寻址方式,主要分为数据寻址和指令寻址二大类。
程序被启动时,程序所包含的指令和数据都被装入到内存中。在程序指令过程中需要取指令和操作数,确定指令存放位置的过程称为指令寻址方式,确定操作数存放位置的过程称为数据寻址方式。
指令寻址(找到下一条将要执行指令的地址)
指令基本上按执行顺序存放在主存中,执行过程中,指令总是从主存内存单元被取到CPU控制器的指令寄存器IR中。一般来说指令寻址只有二种方式:
顺序寻址:顺序执行时,用CPU控制器的程序计数器(PC) + "1"来得到下一条指令的地址;
跳跃寻址:跳转执行时,通过转移指令的寻址方式,计算出目标地址,送到PC中即可;目标转移地址的形成方式主要有三种:立即寻址(直接地址)、相对寻址(相对地址)和间接寻址(间接地址)。
数据寻址(找到当前正在执行指令的数据地址)
开始时,数据被存放在内存中,但是在指令执行过程中,内存中数据可能被装入到CPU的寄存中,或者内存的堆栈区中;还有的操作数可能是IO端口中的内容,或者本身就包含在指令中(即立即数)。另外运行的结果也可能要送到CPU的寄存器中、堆栈中、IO端口或内存单元中。所以数据的寻址要涉及对寄存器(指令中只需要直接给出寄存器编号)、内存单元、堆栈区(指令中不需要给出操作数的地址,数据的地址隐含地由堆栈指针给出)、IO端口(当某个IO接口中寄存器内容要与CPU中寄存器内容交换时要用到IO指令,在IO传送指令中需要提供IO端口号)、立即数(操作数是指令地一部分)的访问。此外操作数可能是某个一维或者二维数组的元素,因此还要考虑如何提供相应的寻址方式、以方便地在内存中找到数据元素。综上,数据地寻址比指令地寻址要复杂得多。
绝大多数情况下,地址码字段通常不代表操作数的真实地址,而是形式地址,那怎样将形式地址转换为真实地址?没错就是通过各种各样的数据寻址方式来转换。
4)常见的数据寻址方式
a.立即寻址(通常用于对某寄存器或者内存单元赋初值)
直接给出操作数,不需要给出地址去其他地方找操作数。采用立即寻址特征的指令只需要在取指令时访问存储器,而在执行阶段不必再访问存储器。
b.直接寻址(EA=A)
指令中直接给出操作数的有效地址,即直接可以通过该地址找到操作数,而不需要经过某些变换。在执行阶段需要根据地址A访问一次储存器去取操作数,取出的操作数送到运算器。
一般指令地址字段的位数比较小,所以直接寻址的寻址访问可能比较小,可以用下面的间接寻址方式来解决这个问题。
c.隐含寻址(缩短指令字长)
指令中不明显地给出操作数地址,其操作数地址隐含在操作码或者某个寄存器中。比如一地址格式的加法指令,操作码为ADD,说明肯定至少需要二个操作数才能做加法运算,而地址码字段仅仅给出了一个操作数的地址,那另一个操作数就在隐含在累加器ACC中。
d.间接寻址(扩大寻址范围,易于完成子程序返回)
指令给出的地址是操作数有效地址的地址,间接寻址分为一次间接寻址(EA=(A))和多次间接寻址。对于N次间接寻址在指令的执行阶段还需要访问N+1次存储器(前N次找操作数的有效地址,第N+1次找操作数)
e.寄存器寻址(指令字较短,指令执行速度较快)
基本和直接寻址类似,在直接寻址的指令中,地址码字段给出的是主存地址,而在寄存器寻址的指令中地址码字段直接给出了寄存器编号Ri(注意这里给的是寄存器的编号,即使计算机有1024个寄存器,那么一个操作数的地址也仅仅需要10bit来表示即可,所以可以大大减少指令的长度),则操作数的有效地址EA=Ri。
由于操作数在寄存器中,因此指令在执行阶段不需要访存,即减少了执行时间。
f.寄存器间接寻址(扩大寻址范围)
和寄存器寻址的不同在于,Ri里的内容不是操作数,而是操作数所在主存单元的地址号,既EA=(Ri)。这种寻址方式需要访问一次存储器去取操作数,这相对于寄存器寻址来说是一个小缺陷。
g.基址寻址(常用于为程序或数据分配存储空间)
基址是什么?字面意思就是操作数的有效地址需要通过某个基础地址来形成。这个地址放在哪里呢?通常需要放在一个基址寄存器BR,其操作数的有效地址EA等于指令中的形式地址A于基地址寄存器中的内容(称为基地址)相加。EA=A+(BR)
基址寄存器BR的内容由操作系统确定,在程序执行过程中不能由用户随意改变,用于可以操作形式地址A。
h.变址寻址(主要用于处理数组问题)
变址寻址的有效地址EA等于指令中的形式地址A与变址寄存器IX的内容相加之和,即EA=A+(IX)。在变址寻址中变址寄存器的内容是用户设定的,在程序执行过程中其值可变,而指令中的形式地址A是不可变的。这点恰好与基址寻址相反。
问什么适合处理数组问题和循环程序?由于变址寄存器的内容可由用户改变,因此处理数据问题时,只需要将指令中的形式地址设置数组首地址,然后用户只需要不断改变变址寄存器IX的内容即可。当然更智能的方式是让变址寄存器的内容自加。
一般来说变址寻址经常和其他寻址方式混合在一起使用,如先间址寻址再变址寻址,此时EA=(A)+(IX);相反,如果先变址寻址再间址寻址,那么EA=(A+(IX))。
i.相对寻址(用于转移指令和程序浮动)
相对寻址基于程序的局部性原理。其有效地址EA是将程序计数器PC的内容与指令中的形式地址A相加而成,即EA=(PC)+A。相对寻址通常有二个用途:
用途一:用于转移类指令,转移后的目标地址与当前指令有一段距离,称为相对位移量,此位移量由指令的形式地址给出,故A又称为位移量。位移量可正可负,通常用补码表示。假设位移量为8bit,则指令当前寻址范围:(PC)+127 ~ (PC)-128。这是由于8bit补码的表示范围是-128~127。
用途二:便于编制浮动程序。即程序的正确运行不受程序所在物理地址的限制。
5)高级语言与机器语言的对应
虽然不需要知道任何一个C语言程序对应的汇编是什么,因为这是编译器的工作,并且对于同一个C语言程序,不同编译器编译的结果也可能是有细微差别的。
但是对于底层开发的程序员需要将C语言与汇编语言和机器语言的一些语句之间简单的对应关系对应起来,比如if-else语句、while语句、函数调用语句等与机器语言的对应关系。
四、指令在CPU中的执行过程和信息流(微操作命令分析)
信息流是根据指令要求依次访问的数据序列,在指令执行的不同阶段,要求访问的数据序列是不同的,而且对于不同的指令,它们的数据流往往也是不同的。
对于一条指令执行过程的不同周期(机器周期)如下所示,其中每个机器周期都有若干个时钟周期组成,每个时钟周期进行 一个微操作。
1)取指周期
该周期的操作为:按PC内容取出指令,并将PC内容递增。当出现转移情况时,指令地址在执行周期被修改。取址周期的信息流/微操作命令:
1)(PC)->MAR //将要执行指令的主存地址放到MAR
2)1->R //发出读命令
3)M(MAR)->MDR //将要执行的指令从主存读到MDR
4)(MDR)->IR //将要执行的指令打入IR
5)OP(IR)->CU //将指令的操作码字段送到CU
6)(PC)+1 -> PC //形成下一条指令的地址
2)间址周期(并不是所有的指令的执行过程都有这个周期)
该周期是为了取出操作数的有效地址,操作数的地址存放在指令所对应的存储器(或者寄存器中)中,然后到其对应的存储器中去取操作数。间址周期的信息流/微操作命令:
1)AD(IR)->MAR //将指令的地址码字段(形式地址)打入MAR
2)1->R //发出读命令
3)M(MAR)->MDR //将有效地址从主存打入MDR
3)执行周期
不同指令的执行周期操作命令不一样,下面举2个典型的例子。
示例一:加法指令,假设一个操作数在ACC,一个操作数在主存A单元中,并且运算结果送至ACC,则具体的微操作命令:
1)AD(IR)->MAR //将指令的地址码字段送入MAR
2)1->R //启动存储器读
3)M(MAR)->MDR //将MAR所指的主存单元中的内容(操作数)经数据总线读到MDR
4)(ACC)+(MDR)->ACC //给ALU发送加命令,加后结果存放在ACC
示例二:存数指令,假设将上述ACC的结果存于主存的A地址单元中
1)AD(IR)->MAR //将指令的地址码字段送入MAR
2) 1->W //启动存储器读
3)(ACC)->MDR //将ACC的内容送至MDR
4) (MDR)->M(MAR) //将MDR的内容写到所指的主存单元中
4)中断周期
执行周期结束后,CPU需要查询是否有请求中断的事件发生,如果有,则进入中断周期。中断隐指令保存的断点存在哪里?怎么寻找中断服务程序的入口地址?只有这二个问题确定了才能写出微指令序列。
前提:现假设程序断点保存在主存的"0"号单元,且采用硬件向量法寻找入口地址。中断周期的微操作命令如下:
1)0->MAR //将主存"0"号单元的地址送入MAR
2)1->W //启动存储器写
3)(PC)->MDR //将PC的内容(程序断点)送入MDR
4) (MDR)->M(MAR) //将MDR里的内容送入MAR所指示的主存单元
5) 向量地址->PC //将向量地址形成部件的输出送至PC
6) 0->EINT //关中断,将运行中断触发器清零
以上便是中断周期的全部微指令操作,如果断点不是存入主存,而是存入栈,那么只需要将上述步骤1)改为(SP)-1->SP, 且(SP)->MAR //这里假设先修改指针后存入数据
五、指令流水线的实现
要使流水线有好的性能,必须使流水线畅通不发生断流。但是由于流水过程会发生如下三种相关冲突,因此流水线不断流是困难的
1)资源相关(又称为结构相关/结构冒险)
指多条指令进入流水线后在同一时钟周期使用了同一个功能部件发生的冲突,不如上面提到的6级流水线中第一条指令的取操作数FO和第四条指令的取指令FI都要访问存储器。当数据和指令放在同一个存储器且只有一个访问口时,便发生二条指令争用存储器资源的相关冲突。
如何解决资源相关冲突
所以解决办法就是将第四条指令FI段停顿一个时钟周期再启动;或者增加一个存储器将指令和数据分别放在二个存储器中。
2)数据相关(又称为数据冒险)
在一个程序中,如果必须等前一条指令执行操作完毕后,才能执行下一条指令,那么这二条指令就是数据相关。数据相关分为三类:
Read After Write:字面理解是应该先写入再度,而现在是没有写入就已经开始读了,出现错误。即读了旧数据
Write After Read:字面理解是应该先读取再写入,而现在是写入后再读取,出现错误。即本来应该读旧数据现在却读到了新数据
Write After Write:自面理解是前面一条指令先写数据,然后后面一条指令再写。而现在恰好相反了导致数据错误
如何解决数据相关冲突
最简单的方式就是使读操作延后,直到数据写入再去读。但是一般使用数据旁路技术来解决:设置相关专用通路,即不等前一条指令把计算结果写回寄存器组,而是把前一条指令的计算结果作为输入数据给下一条需要此结果的指令(下一条指令不再读寄存器组),使本来需要暂停的操作变得可以继续执行。
3)控制相关(又称为控制冒险)
控制相关冲突是由转移指令引起的。当执行转移指令时,依据转移条件的产生结果,可能顺利执行下一条指令;也可能转移到新的目标地址取指令,从而使流水线断流。
如何解决控制相关冲突
采用"猜测法"技术,机器先选定转移分支中的一个,按它取指并处理,条件码生成后,如果猜测正确,那么流水线继续进行下去;如果猜测错误,那么之前预取的指令失效。
六、多处理器基本概念
多处理器系统是指计算机系统中同一时间又多个处理硬件处理不同的指令及数据
1)指令级别多处理器系统
1966年,Michael.J.Flynn提出按指令流和数据流的多倍性对计算机系统结构进行分类。
■指令流 是指机器执行的指令序列;
■数据流 是由指令流调用的数据序列,包括输入数据和中间结果;
■多倍性 是指在系统最受限制的部件上,同时处于同一执行阶段的指令或数据的最大数目。
Flynn分类法的局限
■分类的对象主要是控制驱动方式下的串行处理和并行处理计算机。对于非控制驱动方式的计算机,就不适合采用Flynn分类法;
■把两个不同等级的功能并列对待,通常,数据流受指令流控制从而造成MISD不存在;
■分类太粗,对流水线处理机的划分不明确,标量流水线为SISD,向量流水线为SIMD。
SISD(Single Instruction Single Data)
处理器串行执行指令;或者处理器内采用指令流水线,以时间重叠技术实现了一定程度上的指令并行执行;甚至于处理器是超标量处理器,内有几条指令流水线实现了更大程度上的指令并行执行。但它们都是以单一的指令流从存储器取指令,以单一的数据流从存储器取操作数和将结果写回存储器(一个单处理器指向一个单指令流,对保存在一个存储器中的数据程序进行操作)。
SIMD(Single Instruction Mutiple Data)
有单一的控制部件,但是有多个处理部件。计算机以一个控制单元从存储器取单一的指令流,一条指令同时作用到各个处理单元,控制各个处理单元对来自不同数据流的数据组进行操作(一个机器指令控制多个处理部件,步伐一致的同时执行;每个处理部件都有一个相关的数据处理空间,因此,每条指令由不同的处理部件在不同的数据集合上执行)。这种体系结构的典型代表是阵列处理机,一些学者认为将向量处理机也划入此类。
SIMD在性能上有什么优势呢?以加法指令为例,单指令单数据(SISD)的CPU对加法指令译码后,执行部件先访问内存,取得第一个操作数;之后再一次访问内存,取得第二个操作数;随后才能进行求和运算。而在SIMD型CPU中,指令译码后几个执行部件同时访问内存,一次性获得所有操作数进行运算。这个特点使得SIMD处理器在数字信号、图像、多媒体信息等数据密集型任务的处理非常有效
向量处理器(Vector Processor)
是一种特殊的SIMD处理器,是一种实现了直接操作一维数组(向量)指令集的CPU。其一条指令(向量指令)可以完成一整个向量(数组)的输入,并同时处理这些连续且相似的数据项,向量处理器有用一个控制单元,但有多个执行单元,可以对向量的不同数据元素执行相同的操作。
MISD(Mutiple Instruction Single Data)
多个处理单元,各配有相应的控制单元。各个处理单元接收不同的指令,多条指令同时在一份数据上进行操作(一系列数据被传送到一组处理器上,每个处理器执行不同的指令序列)。这种计算机体系结构是一种比较奇怪的组合,这已经被证明是不可能至少是不实际的,目前为止还不存在这种类型的计算机。
MIMD(Mutiple Instruction Mutiple Data)
同时有多个处理单元,并且每个处理单元都配有相应的控制单元。各个处理单元可以接收不同的指令并对不同的数据流进行操作(一组处理器同时在不同的数据集上执行不同的指令序列)。大多数现代的并行计算机都属于这一类,多处理机系统和多计算机系统都是MIMD型的计算机。
MIMD可以根据处理器的通信进一步细化:如果每个处理器都有一个专用的存储器,则每个处理部件都是一个独立的计算机。计算机间的通信或者借助于固定的路径,或者借助于某些网络设施,这类系统称为集群系统。如果处理器共享一个公用的存储器,每个处理器都访问保存在共享共享存储器中的程序和数据,处理器之间通过这个存储器进行相互通信,这类系统称为共享存储器多处理系统。而共享存储器多处理器系统可以根据“如何把程序分配给处理器”,分为主/从结构和对称结构
主/从结构:
在主/从结构中,操作系统的内核的内核总是运行在某个特定的处理器上,其他处理器用于执行用于程序和操作系统的使用程序。主处理器负责调度进程或者线程,如果一个处于运行的进程或者线程需要使用系统的服务(如一次I/O调用),则它必须给主处理器发送请求,并等待服务的处理。
这种方式非常简单,一个处理器控制了所有存储器和I/O资源,因此可以简化冲突的解决方案。但是这种方式也有明星缺点:
1)主处理器的失败将导致整个系统失败。
2)由于主处理器必须负责所有进程的调度和管理,因此可能称为性能瓶颈。
对称结构(SMP):
在对称多处理系统中,内核可以在任何处理器上执行,并且每个处理器可以从可用的进程或者线程池中进行各自的调度工作。内核也可以由多进程或者多线程构成,允许部分内核并行执行。
SMP方法增加了操作系统的复杂度,它必须确保二个处理器不会选择同一个进程,并且要确保队列不会丢失,因此需要解决同步问题。
2)虚拟核心级别多处理器系统
硬件线程
也成为逻辑内核或逻辑处理器或虚拟核心,是由CPU硬件提供,为操作系统屏蔽了具体的执行细节。比如Windows系统将每一个硬件线程识别为一个可调度的逻辑处理器,每个逻辑处理器可以允许软件线程的代码;Windows系统调度器可以决定将一个软件线程赋给一个硬件线程,通过这种方式均衡每一个硬件线程的工作负载,以达到并行优化的目的。
硬件线程是与CPU绑定的,即固定的某种CPU,其对操作系统提供的硬件线程数量是固定不可改变的;而与之相对的概念-软件线程(包括用户级线程和内核级线程)是由操作系统模拟出的可调度线程,其数量在操作系统运行时可以被动态改变。
硬件线程由CPU提供,为操作系统屏蔽了具体CPU的执行细节,最多支持的硬件线程数目是CPU出厂时已经定了;内核线程由操作系统提供,为用户程序的用户级线程屏蔽了操作系统执行的细节,最多支持的内核线程和用户线程数量则是无法确定的,这些是操作系统决定的。
3)物理核心级别多处理器系统
多核处理器
将多个CPU物理核心集成到单个芯片中。每个CPU物理核心都是一个单独的处理器,拥有自己单独的ALU运算单元、寄存器、控制器、Cache等;每个CPU物理核心都拥有处理器的译码单元,能同时处理多条指令,由此可见多核处理器是MIMD
在现代的多核物理结构中,内存对多个CPU物理核心是共享的。而每个CPU物理核心又可以虚拟出多个硬件线程("超线程技术")供操作系统调度。在不同CPU物理核心上的不同线程在硬件上是完全并行的,而在同一个CPU物理核心上的不同线程是采用时间交替的方式轮流执行的。
比如Intel i9-12900k处理器宣传有16核心,24线程。这里的核心指的是物理核心,线程指的是硬件线程。
七、CPU对外部I/O的控制
1)I/O接口(I/O控制器)和I/O端口的区别
I/O接口是主机和外设之间传送信息的桥梁,介于主机和外设之间。主机控制外设的命令信息、传送给外设的数据或从外设取来的数据、外设送给主机的状态信息等都要先存放在I/O接口中。
所以I/O接口中有一些寄存器,用于存放这些命令、数据和状态信息,把I/O接口中这些寄存器称为I/O端口(目前CPU对I/O端口的编址方式有统一编址和不统一编址)。
2)总线周期和存取周期
存储器和I/O接口是挂接在总线上的,CPU对存储器和I/O接口的访问通过总线实现;把CPU通过总线对微处理器外部(存储器或I/O接口)进行一次访问所需时间称为一个总线周期。
而存储周期指两次独立访问存储器操作之间的最小间隔,包含存取时间和恢复时间;其中存取时间指从启动一次存储器操作到完成该操作所经历的时间。
为什么需要设置I/O接口?
1)某些I/O设备速度比较慢,与CPU的速度相差可能很大,通过I/O接口可以实现数据缓冲
2)一台机器通常配有多台I/O设备,它们各自有其设备编号,通过I/O接口可以实现I/O设备的选择
3)I/O控制方式(每种控制方式都需要在I/O接口中有相关的硬件电路支持)
a.程序查询方式
又称为程序控制I/O方式。CPU每时每刻都要查询I/O设备是否准备就绪
b.程序中断方式
只有I/O设备发出中断请求时,CPU才停下自己的事来响应中断。
c.DMA方式
是一种完全由硬件进行成组信息传送的控制方式,信息传送不再经过CPU,而在外设和内存之间直接进行,这也是为什么名字叫直接存储器存取方式的原因。这种方式适用于硬盘、显卡等高速I/O设备大批量数据的传送。在DMA方式中中断的作用主要是做一些DMA结束时的工作。
d.通道方式
4)DMA的一些核心点
a.DMA的传送方法
如果出现高速IO(通过DMA接口(DMA控制器))和CPU同时访问主存怎么办?这时CPU就得将总线的占有权让给DMA接口用,即DMA采用周期窃取的方式占用一个周期。通常DMA与主存交换数据时采用以下3种方法。
1)停止CPU访问主存
当外设需要传送一片数据时,由DMA接口向CPU发送一个信号,要求CPU放弃地址线、数据线和有关控制线的使用权,DMA接口获得总线控制权后,开始进行数据传送。在数据传送结束后,DMA接口通知CPU可以使用主存,并把总线控制权交换给CPU。这种传送过程CPU基本处于不工作状态或者保持原始状态。
2)周期挪用
基本思想是,当外设准备昊一个数据时,DMA控制器就向CPU申请一次总线控制权,CPU在一个总线事务结束时一旦发现有DMA请求,就立即释放总线,让出一个存储周期给DMA控制器,由DMA控制器控制总线在主存和外设之间传输一个数据,传输结束后立即释放总线,下次外设准备好数据时,又重复上述过程,直到所有数据传送完毕。这种情况CPU的工作几乎不受影响,知识在万一出现访存冲突时,CPU挪出一个存储周期给DMA,由DMA访问主存,而CPU延迟访问主存。
I/O设备每挪用一个主存周期(主存存储周期)都要申请总线控制权,建立总线控制权和归还总线控制权
3)DMA与CPU交替访问主存
这种方式适用于CPU的工作周期比主存存取周期长的情况,例如CPU的工作周期是1.2us,主存的访存周期小于0.6us,那么可以将一个CPU周期分为C1和C2二个周期,其中C1专供DMA访存,C2专供CPU访存。
这种方式不需要总线使用权的申请,建立和归还过程,总线使用权是通过C1和C2分时控制的。实际上总线变成了在C1和C2控制下的多路转换器,总线控制器的转移几乎不需要时间,具有很高的DMA传送效率。CPU即不停止主程序的运行,也不进入等待状态,完成了DMA的数据传送。
b.DMA方式下,在主存和外设之间有一条物理通路直接相连吗?
没有。通常所说的DMA方式下数据在主存和外设之间直接进行传送,其含义并不是说在主存和外设之间建立一条物理上的直接通路,而是在主存和外设之间通过外设接口、系统总线以及总线桥接部件等连接,建立起一个信息可以互相通达的道路。“直接通路”是逻辑上的含义。比如物理上磁盘和主存不是直接相连的。
c.CPU对DMA请求和中断请求的响应时间是否一样?
不一样。DMA方式下,向CPU请求的是总线控制权,要求CPU让出总线控制权给DMA控制器(DMA接口),由DMA控制器来控制总线完成主存与外设之间的数据交换,所以CPU只要用完总线后就可以响应请求,释放总线,让出总线控制权。CPU总是在一次总线事务完成后响应,所以对DMA响应时间应该少于一个总线周期; 而中断方式下请求的是CPU时间,要求CPU中止正在执行的程序,转到中断服务程序去执行,通过执行中断服务程序,对中断事件进行相应的处理。CPU总是要等到一条指令结束后采取查询有无中断请求,所以响应时间少于一个指令周期的时间。
d.与程序中断方式相比,DMA方式有哪些特点?
1)从数据传送来看,程序中断方式靠中断方式传送,DMA方式靠硬件传送
2)从CPU响应时间来看,程序中断方式是在一条指令执行结束时响应,而DMA方式可在指令周期内的任意存储周期结束时响应
3)程序中断方式有处理异常事件的能力;DMA方式没有这种能力,主要用于大批数据的传送
4)程序中断方式需要中断现行程序,故需要保护现场; DMA方式不需要中断现行程序,无需保护现场(由于数据传送不经过CPU,也就不需要保护,恢复CPU现场等繁琐操作)。