第一章 计算机组成与体系结构
1.1 计算机系统组成
1.1.1 计算机硬件的组成
- 控制器。控制器是分析和执行指令的部件,也是统一指挥并控制计算机各部件协调工作的中心部件,所依据的是机器指令。控制器的组成包含如下:
- 程序计数器PC:存储下一条要执行指令的地址;
- 指令寄存器IR:存储即将执行的指令;
- 指令译码器ID:对指令中的操作码字段进行分析解释;
- 时序部件:提供时序控制信号。
- 运算器。也成算数逻辑单元(ALU),主要功能是在控制器的控制下完成各种算术运算和逻辑运算。运算器的组成包含如下:
- 算数逻辑单元ALU:数据的算数运算和逻辑运算;
- 累加计数器AC:通用寄存器,为ALU提供一个工作区,用在暂存数据;
- 数据缓冲寄存器DR:写内存时,暂存指令或数据;
- 状态条件寄存器PSW:存状态标志与控制标志。
- 主存储器。也称为内存储器(通常简称主存或内存),存储现场操作的信息于中间结果,包括机器指令和数据。
- 辅助存储器。也称外存储器,通常简称外存或辅存。存储需要长期保存的各种信息。
- 输入设备。
- 输出设备。
1.1.2 计算机系统结构的分类
1. 存储程序的概念
2. Flynn分类
根据指令流、数据流的多倍性特征对计算机系统进行分类。根据不同的指令流-数据流组织方式,将计算机系统分为以下四类:
- 单指令流单数据流SISD
- 单指令流多数据流SIMD
- 多指令流单数据流MISD
- 多指令流多数据流MIMD
1.1.3 复杂指令集系统于精简指令集系统
1. 复杂指令系统计算机CISC指令系统的特点
- 指令数量众多,通常有100-250条
- 指令使用频率相差悬殊
- 支持很多种寻址方式。通常为5-20种
- 变长的指令。指令长度不固定
- 指令可以对于主存单元中的数据直接进行处理。执行速度较慢
- 以微程序控制为主
2. 精简指令系统RISC的特点
- 指令数量少。
- 指令的寻址方式少。通常只支持寄存器、立即数、相对寻址方式等。
- 指令长度固定。
- 以硬布线逻辑控制为主。
- 单周期指令执行,采用流水线技术。
- 优化的编译器。
- CPU中通用寄存器数量多,一般在32个以上,有的可达上千个。
大多数RISC采用了Cache方案,使用Cache来提高取指令的速度。而且,有的RISC使用两个独立的Cache来改善性能,一个称为指令Cache,另一个称为数据Cache。这样,取指令和取数据可以同时进行,互不干扰。
1.1.4 总线
是一组能为多个部件分时共享的公共信息传输线路。共享是指总线上可以挂接多个部件,各个部件之间相互交换的信息都可以通过这组公共线路传送;分时是指同一时刻只允许有一个部件向总线发送信息,如果出现两个或两个以上部件同时向总线发送信息,势必导致信号冲突。当然,在同一时刻,允许多个部件同时从总线上接收相同的信息。
按总线相对于CPU或其他芯片的位置可以分为内部总线和外部总线两种。在CPU内部,寄存器之间和算数逻辑部件ALU与控制部件之间传输数据所用的总线称为内部总线;外部总线是指CPU与内存RAM、ROM和输入/输出设备接口之间进行通信的线路。由于CPU通过总线实现程序取指令、内存/外设的数据交换,在CPU与外设一定的情况下,总线速度是制约计算机整体性能的最大因素。
按总线功能来划分,又可以分为地址总线、数据总线、控制总线三类,人们通常所说的总线都包括这三个组成部分,地址总线用来传送地址信息,数据总线用来传送数据信息,控制总线用来传送各种控制信号。
1.2 存储器系统
用来存放程序和数据的部件。
传统的存储器系统一般分为高速缓冲存储器(Cache)、主存、辅存三级。
- 主存可由CPU直接访问,存储速度快,但是容量较小,一般用来存放当前正在执行的程序和数据。
- 辅存直接设置在主机外部,存储容量大,价格较低,但存取速度较慢,一般用来存放暂时不参与运行的程序和数据,CPU不可以直接访问辅存,辅存中的程序和数据在需要时才传送到主存。
- 当CPU速度很高时,为了使访问存储器的速度能与CPU的速度相匹配,又在主存和CPU间增设了一级Cache。Cache的存取速度比主存速度更快,但是容量更小,用来存放当前最急需处理的程序和数据,以便更快速的向CPU提供指令和数据。
多层级的存储体系之所以能用低投入换来较高的存取速率,得益于局部性原理。局部性原理是指程序在执行时呈现出局部性规律,即在一较短的时间内,程序的执行仅局限于某个部分。相应的,它所访问的存储空间也仅局限于某个区域。程序局限性包括时间局部性和空间局部性,时间局部性是指程序中的某条指令一旦执行,不久以后该指令可能再次执行。产生时间局部性的典型原因是由于程序中存在着大量的循环操作;空间局部性是指一旦程序访问了某个存储单元,不久以后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址可能集中在一定的范围内,其典型情况是程序顺序执行。
存储器中常用的存储方式:
- 顺序存取:存储的数据以记录的形式进行组织。对数据的访问必须按特定的顺序进行。磁带存储器
- 直接存取:与顺序存储相似。直接存储使用一个共享的读写装置对所有的数据进行访问。但是,每个数据块都有唯一的地址标识,读写装置可以直接移动到目的数据块所在位置进行访问,存取时间也是可变的。硬盘存储器。
- 随机存取:存储器的每一个可寻址单元都具有自己唯一的地址和读写装置,系统可以在相同的时间内对任意一个存储单元的数据进行访问,而与先前的访问序列无关。主存储器。
- 相联存取:是随机存取的一种形式,但是选择某一单元进行读写时取决于其内容而不是其地址。每个单元都有自己的读写装置,读写时间也是一个常数,使用相联存取方式,可以对所有的存储单元的特定位进行比较,选择符合条件的单元进行访问。Cache。
1.2.1 主存储器
用来存放计算机运行期间所需要的程序和数据,CPU可以直接随机的进行读/写。主存具有一定容量,存取速度较高。由于CPU要频繁的访问主存,所以主存的性能在很大程度上影响了整个计算机系统的性能。主存可以分为随机存取存储器和只读存储器。
- 随机存取存储器
RAM,可写入读出,但断电后信息无法保存,因此只能用于暂时存储数据。可分为DRAM动态存储和SRAM静态存储两种。DRAM的信息会随时间逐渐消失,因此需要定时对其刷新维持信息不丢失;SRAM在不断电的情况下信息能够一直保持而不会丢失。DRAM密度大于SRAM且更加便宜,但SRAM速度快,电路简单,容量小,价格高。 - 只读存储器
ROM,可以看作RAM的特殊形式,特点是:存储器的内容只能随即读出而不能写入。一旦写入,固定不变,即使断电,写入的内容也不会丢失,又称固定存储器。用来存放系统程序BIOS - 主存编址方法
计算机系统中,存储器中每个单元的位数时相同且固定的,成为存储器编址单位。主要分为字编址和字节编址
1.2.2 辅助存储器
用于存放当前不需要立即使用的信息,一旦需要,再和主机成批交换数据。主机的外部设备,称为外存储器。存储容量大、可靠性高、价格低。
1. 磁带存储器
顺序存取的设备,特点为:存取时间较长,但存储容量大,便于携带,价格便宜。
2. 磁盘存储器
在磁盘上进行信息的读写时,首先要定位到目标磁道,这个过程称之为寻道,寻道所消耗的时间成为寻道时间,定位到目标磁道后,需要定位到目标扇区,此过程通过旋转盘片完成,平均旋转半圈可到目标位置,故磁盘访问时间为:
$$磁盘访问时间(存取时间)=寻道时间+旋转延迟时间$$
1.2.3 Cache存储器
功能是为了提高CPU数据输入输出的速率,即CPU与存储系统间数据传送带宽限制。通常在CPU和内存之间设置小容量的Cache。
Cache采用相联存储器CAM,是一种基于数据内容进行访问的存储设备。对其写入数据时,CAM能够自动选择一个未用的空单元进行存储;当需要读出数据时,而是直接给出该数据或该数据的一部分内容。CAM通过对所有存储单元中的数据同时进行比较,并标记符合条件的所有数据以供提取。比较是同时、并行进行的。
1. Cache基本原理
使用Cache改善性能的依据是程序的局部性原理。
根据局部性原理,可以爸目前常用或将要用到的信息预先放到Cache中,当CPU需要读取数据时,首先在Cache中查找是否有所需内容,如果有,则直接从Cache中读取;若没有,再从内存中读取该数据,然后同时送往CPU和Cache。如果CPU需要访问的内容大多都能在Cache中找到(称为访问命中),则可以大大提高系统性能。
如果以$h$代表对Cache的访问命中率($1-h$称为失效率,或未命中率),$t_1$表示Cache的周期时间,$t_2$表示内存的周期时间,以读操作为例,使用“Cache+主存储器”的系统的平均周期为$t_3$,则:
$$t_3=t_1\times h+t_2\times (1-h)$$
系统的平均存储周期与命中率有很密切的关系,命中率的提高即使很小也能导致性能的极大改善。
例如:设某计算机主存的读/写时间为100ns,有一个指令和数据合一的Cache,已知该Cache的读/写时间为10ns,取指令的命中率为98%,取数的命中率为95%,在执行某类程序时,约有$1/5$指令需要存/取一个操作数。假设指令流水线再任何时候都不阻塞,则设置Cache后,每条指令的平均访存时间约为:
$$(2%\times 100ns+98%\times 10ns)+1/5\times (5%\times 100ns+95%\times 10ns)=14.7ns$$
2. 映射机制
当CPU发出访存请求后,存储器地址先被送到Cache控制器以确定所需数据是否已在Cache中,若命中则直接对Cache进行访问。这个过程称为Cache的地址映射(映像)。在Cache的地址映射中,主存和Cache将均分成容量相同的块(页)。常见的映射方法有直接映射、全相联映射和组相联映射。
1) 直接映射
以随机存储器作为Cache存储器,硬件电路较简单。在进行映射时,主存地址被分成三个部分,从高到低一次为:区号、页号、页内地址。
区号 | 页号 | 页内地址 |
---|---|---|
7位 | 4位 | 19位 |
- | Cache地址 | Cache地址 |
例如:内存容量为1GB,Cache容量为8MB,页大小为512KB。直接映像中,先分区,再分页。一个区的大小就是Cache容量的大小,所以一共分:1GB/8MB=128个区,所以区号为7位。每个区分:8MB/512KB=16个页,所以页号为4位。
直接映射方式中,没个内存也只能复制到某一固定的Cache页中。映射规律为:主存中每个区的第0页,只能进入Cache的第0页。若当前时刻Cache中0号页已被占据,而1-15号页空闲,现在要将1区的第0页(即内存的16页)调入Cache是会发生冲突的。所以直接映射的块冲突率非常高。
在Cache中,为每一个页设立一个Cache标记,该标记用于识别当前的Cache块来自于哪个内存页。直接映像中,由于每个区的N号页,都必须进入到Cache的N号页,所以只需要记录区号即可。所以此时标记位的长度为7位。
直接映射方式的优点是比较容易实现,缺点是不够灵活,有可能使Cache的存储空间得不到充分利用。
2) 全相联映像
使用相联存储器组成的Cache存储器。该方式中,主存中的每一页可以映射到Cache的任一页。如果淘汰Cache中某一页的内容,则可调入任一主存页的内容,因此比直接映射方式更为灵活。
在全相联映射方式中,主存地址分为两个部分,分别为地址部分(主存页标记)和数据部分(页内地址)。数据部分用来存放数据,而地址部分则存放该数据的存储器地址。
页号 | 页内地址 |
---|---|
11位 | 19位 |
主存页号 |
因为Cache中某一页的内容都可以在主存中的任一页中存储,所以在Cache中也需要存储该页所对应的主存页号,所以,Cache标记信息位数增加,比较逻辑成本随之增加。
在全相联映射方式中,主存地址不能直接提取Cache页号,而是需要将主存页标记于Cache各页的标记诸葛比较,直到找到符合标记的页(访问Cache命中),或者全部比较完成仍无符合的标记(访问Cache失败)。因此这种映射方式速度很慢,是掉了高速缓存的作用,也是该方式的最大缺点。因此只适用于小容量Cache。
3) 组相联映射
也称页组映射,介于直接映射和全相联映射之间,是这两种映射的折衷方案。全相联映射以页为单位,可自由映射,没有固定的对应关系,直接映射方式中,主存分组,主存组内的各页与Cache的页之间采取的是固定的映射关系,但各组均可映射到Cache中。在组相联映射中就,主存和Cache都分组,主存中的一个组内的页数与Cache的分组数相同。
区号 | 组号 | 组内页号 | 页内地址 |
---|---|---|---|
7位 | 3位 | 1位 | 19位 |
- | Cache地址 | Cache地址 | Cache地址 |
组关联映射的规则为:主存中的组于Cache中的组形成直接映射关系,而每个组内的页是全相联映射关系。如主存中1区0页,它在0组中,所以只能进入Cache中的0组中,至于进入到Cache中的0组0页还是0组1页,并无强制要求,可以任意放置。
如果Cache中每组只有一页,则组相联映射方式就变成了直接映射方式,如果Cache中每组页数为16页(即Cache只分一组),那就是全相联映射。
在组相联映射中,由于Cache中每组有若干可以选择的页,因而它在映射定位方面较直接映射方式灵活;每组页数有限,因此付出的代价不是很大,可以根据设计目标选择组内页数。
3. 替换算法
当Cache中产生了一次访问未命中之后,相应的数据应同时读入CPU和Cache。但是当Cache已存满数据后,新数据必须替换(淘汰)Cache中的某些旧数据。
1) 随机算法
最简单的替换算法。完全不管Cache块过去、现在及将来的使用情况,简单的根据一个随机数,选择一块替换掉。
2) 先进先出算法FIFO
按照调入Cache中的先后顺序决定淘汰的顺序,即在需要更新时,将最先进入Cache中的块最为被替换的块。该方法要求为每块做一记录,记下他们进入Cache的先后顺序。这种方法容易实现,而且系统开销小,缺点是可能会把一些需要经常使用的程序块(如循环程序)替换掉。
3) 近期最少使用原则LRU
LRU算法是把CPU近期最少使用的块作为被替换的块。这种替换方法需要随时记录Cache中各块的使用情况,以便确定哪个块时近期最少使用的块。LRU算法相对合理,但实现起来比较复杂,系统开销较大。通常需要对每一块设置一个称为“年龄计数器”的硬件或软件计数器,用以记录其被使用的情况。
4. 写操作
因为需要保证缓存在Cache中的数据与内存中的内容一致,相对读操作而言,Cache的写操作比较复杂。
1) 写直达
当要写Cache时,数据同时写回内存,有时也称为写通。当某一块需要替换时,也不必把这一块写回到主存中去,新调入的块可以立即把这一块覆盖掉。这种方法实现简单,而且能随时保持主存数据的正确性,但可能增加多次不必要的主存写入,会降低存取速度。
2) 写回
CPU修改Cache中的某一块之后,相应的数据并不立即写回内存单元,而是当该块从Cache中被淘汰时,才把数据写回到内存中。在采用这种更新策略的Cache块表中,一般有一个标志位,当一块中的任何一个单元被修改时,标志位被置“1”。当需要替换掉这一块时,如果标志位为“1”,则必须先把这一块写回到主存中去之后,才能再掉入新的块;如果标识为“0”,则这一块不必写回内存,只要用新调入的块覆盖掉这一块即可。这种方法的优点是操作速度块,缺点是因主存中的字块会随时修改而有可能出错。
3) 标记法
对Cache中的每一个数据设置一个有效位。当数据进入Cache后,有效位置“1”;而当CPU要对该数据进行修改时,数据只需要写入内存并同时将该有效位置“0“。当要从Cache中读取数据时需要测试其有效位,若为”1“则直接从Cache中取数,否则,从内存中取数。
1.3 流水线
流水线技术吧一个任务分解为若干顺序执行的子任务,不同的子任务由不同的执行机构负责执行,而这些机构可以同时并行工作。在任一时刻,任一任务只占用其中一个执行机构,这样就可以实现多个任务的重叠执行,以提高效率。
1.3.1 流水线周期
流水线应用过程中,会将需要处理的工作分为N个阶段,最耗时的那一段所消耗的时间为流水线周期。如:使用流水线技术执行100条指令,每条指令取指2ms,分析4ms,执行1ms,则流水线周期为4ms。
1.3.2 计算流水线执行时间
延续上面的场景,将一个任务的执行过程可以分为N个阶段,假设每个阶段的完成时间为t,则完成该任务所需的时间即为Nt。若以传统的形式,则完成k个任务所需的时间为kNt;而使用流水线技术执行,则花费的时间是Nt+(k-1)t。也就是说,除了第1个任务需要完整的时间外,其他都通过并行,节省下了大量的时间。所以流水线的执行时间可以通俗的表达为:
流水线执行时间=第1条指令的执行时间+(n-1)X流水线周期
n代表需要处理的任务数量。
在考试时,需要特别注意一个细节问题,流水线的执行时间计算,其实进一步可以分理论情况和实践情况两种不同的处理方式。下面以实例进行说明。
例:某计算机系统,一条指令的执行需要经历取指2ms,分析4ms,执行1ms三个阶段,现需要执行100条指令,利用流水线技术需要多长时间?
理论上来说,一条指令的执行时间为:2ms+4ms+1ms=7ms
所以理论上流水线的执行时间为:2ms+4ms+1ms+(100-1)X4ms=403ms
而实际上,真正做流水线处理时考虑到处理的复杂性,会将执行的每个阶段的时间都统一为流水线周期,即1条指令的执行周期为4ms+4ms+4ms=12ms。
所以,实际流水线的执行时间为4ms+4ms+4ms+(100-1)X4ms=408ms。考试时,80%以上的概率采用理论公式计算,所以考试时需要以理论公式计算,若计算的结果无正确选项,才考虑使用实际公式计算。
1.3.3 流水线的吞吐率
流水线的吞吐率(Though Put Rate,TP)是指在单位时间内流水线所完成的任务数量或输出的结果数量。计算流水线吞吐率的最基本公示如下:
$$TP=\frac{n}{T_k}$$
$n$为任务数,${T_k}$是处理完成$n$个任务所用的时间。
流水线的最大吞吐率为:
$$TP_{max}=\operatorname*{Lim}_{n\to \infty}\frac{n}{(k+n-1)\Delta t}=\frac{1}{\Delta t}$$
1.3.4 流水线的加速比
完成同样一批任务,使用流水线所用的时间与不使用流水线所用的时间之比成为流水线的加速比(speedup radio)。如果不使用流水线,则顺序执行所用的时间为$T_0$,使用流水线的执行时间为$T_k$,则计算流水线加速比的基本公式如下:
$$S=\frac{T_0}{T_k}$$
如果流水线各个流水段的执行时间都相等(设为$\Delta t$),则一条$k$段流水线完成$n$个连续任务所需要的时间为$(k+n-1)\Delta t$。如果不使用流水线,即顺序执行这$n$个任务,则所需的时间为$nk\Delta t$。因此,各个流水段执行时间均相等的一条$k$段流水线完成$n$个连续任务的实际加速比为:
$$S=\frac{nk\Delta t}{(k+n-1)\Delta t}=\frac{nk}{k+n-1}$$
这种情况下的最大加速比为:
$$S_{max}=\operatorname*{Lim}_{n\to \infty}\frac{nk}{k+n-1}=k$$