计算机组成与体系结构
本文系统梳理了计算机组成与体系结构的核心内容,重点涵盖了计算机的基础概念、数据表示与运算、存储系统与层次结构、指令系统与CPU基本功能、流水线与多处理器系统,以及总线与I/O系统。通过详细阐述寄存器、ALU、控制单元和中断机制的工作原理,以及 Cache、DMA、TLB 等关键技术的实现方式,本文为读者提供了完善的理论框架和复习思路,帮助在研究生招生考试《计算机学科基础》中高效掌握计算机组成部分的要点与难点。
(摘要由 OpenAI o1-preview 生成)
第一章 基础概念¶
(1) 字长篇
指令字长:指令的长度
机器字长:运算单元的长度
存储字长:存储单元的长度
(2) 周期篇
存储周期:CPU 一次读取操作需要的时间
总线周期:总线进行一次数据传输所需的时间
(3) 总线篇
系统总线:CPU 与其他部件之间的通信线路
(4) 编址篇
CPU:按机器字
内存:按块,块内地址为 CPU 地址,后面为 \(\log\) 字长位
高速缓存/Cache:未说明时,块的大小与内存一致
第二章 数据的表示和运算¶
数码表示¶
有 \(\pm 0\):原码、反码。
无 \(\pm 0\):补码、移码。
(1) 原码与补码的转换:正数不变,负数按位取反加一,符号位不变。
(2) 小数的补码表示:无视小数点,全部取反加一(负数时)。
(3) 移码:为每个数添加一个固定的偏移量(通常为 \(2^{n-1} - 1\)),使得所有数都为正数。
(4) 强制类型转换:
a. 等字长时,保持机器中的表示不变,只改变解释方式。
b. 不等字长时,根据目标类型是有符号数或是无符号数,选择有符号拓展或零拓展。当目标类型更短时,截断高位。
运算电路¶
(1) 几个相关标志:
a. ZF:零标志,结果为零时置位。
b. CF:借位或进位标志(此时操作数被看作无符号数)。需要注意,全加器中出现的 CF = C_out ^ C_in
,是因为实际的情况下,C_in
只被用作是指示减法操作的信号。
判断无符号数 \(A \geq B\):\(A - B \geq 0\),\(\text{CF} = 0\)。
判断无符号数 \(A < B\):\(A - B < 0\),\(\text{CF} = 1\)。
c. OF:溢出标志(此时操作数被看作有符号数)。
d. SF:符号标志,结果为负时置位。
判断有符号数 \(A \geq B\):
未发生溢出时:\(A - B \geq 0\),\(\text{OF} = 0\),\(\text{SF} = 0\);
发生溢出时:\(A - B < 0\),\(\text{OF} = 1\),\(\text{SF} = 1\)。
判断有符号数 \(A < B\):
未发生溢出时:\(A - B < 0\),\(\text{OF} = 0\),\(\text{SF} = 1\);
发生溢出时:\(A - B \geq 0\),\(\text{OF} = 1\),\(\text{SF} = 0\)。
e. 计算这些标志:转为十进制下进行计算。只需要注意,计算 CF 时,需要将负号读作 \(2^{n}\)。
(2) 加法器
(3) 乘法器:移位加法器。
32 位乘法器,需要 64+1 位的寄存器作为中间结果的存储。
P 初始为 0,每次加法后,中间结果整体右移一位,将其中的高 32 位与乘数相加,得到新的中间结果。
循环 32 次后,得到最终结果。
+-> (P) add multiplier
| |
| V -------> shift
| +-+-------+-------+
| |C| P | Y |
| +-+-------+-------+
| 1 |32 32
+------+
(4) 除法器:移位减法器。
R 初始为被除数符号拓展。结果中 R 为余数,Q 为商。
32 位有符号整数除法,仅有一种溢出的情况:\(-2^{31} / -1 = 2^{31}\)。
+-> (R) add/sub divisor
| |
| V <------- shift
| +-+-------+-------+
| |C| R | Q |
| +-+-------+-------+
| 1 |32 32
+------+
(5) 在 ALU 中,有时使用模 4 补码,由前最高位决定最终符号,由次高位决定是否溢出:
符号位 | 结果 | 溢出 |
---|---|---|
2'b00 |
+ | |
2'b01 |
+ | overflow |
2'b10 |
- | overflow |
2'b11 |
- |
浮点数表示¶
(1) 规格化浮点数:通过左移或右移,使之成为 1.xxx
形式的小数。(然后,舍弃整数部分,将首位替换为符号位)
(2) IEEE 754 单精度浮点数
符号位 s | 指数位 e | 尾数位 f |
---|---|---|
1 | 8 | 23 |
\(\text{Value} = (-1)^s \times 2^{e-127} \times 1.f\)
指数位 e 被称为阶码,使用偏移量为 127 的移码表示。
尾数位是形如 1.xxx
的规格化小数,并不存储整数部分的 1
。
标准中规定了当 f 和 e 存在零值时的特殊含义:
尾数 f | 阶码 e | 含义 |
---|---|---|
\(0\) | \(0\) | \(\pm 0\) |
\(0\) | \(255\) | \(\pm \infty\) |
\(\neq 0\) | \(0\) | \(2^{-126} \times 0.f\) |
\(\neq 0\) | \(255\) | NaN |
(3) 浮点数的加减法
遵循以下步骤运算:
a. 对阶:将阶码较小的数的尾数右移(保留右溢的部分),直到两者的阶码相等。(保留更大的阶码)
b. 加减尾数:对齐后,直接加减尾数。(之前保留的右溢部分需要参与运算)
c. 规格化:根据结果的尾数是否规格化,调整阶码。
d. 舍入:如果运算结果是不可表示的,需要进行舍入。
第三章 存储系统¶
主存储器¶
存储器使用的地址:行地址、列地址。
(1) SRAM:非破坏性读,无需刷新,行和列专用地址线。
(2) DRAM:破坏性读,需要使用假读定时刷新,按行刷新,行和列复用地址线。
(3) 多模块存储器:
存储器规格:存储单元数 \(\times\) 存储单元的长度,例如 8K \(\times\) 32位。
a. 单体多字:一个存储单元存储多个字,总线一次读出一个存储模块的所有字(字扩展)
b. 多体并行,分两种地址编排,两种启动方式
(4) 多体并行之高位交叉地址编排(位扩展、串联):存储模块 M1、M2、M3、M4 各自连续编址。
(5) 多体并行之低位交叉地址编排(位扩展、串联):存储模块 M1、M2、M3、M4 交叉编址,如图所示:
+----------+-----------+-----------+---------> data: 0 1 2 3
| | | |
+---+---+ +---+---+ +---+---+ +---+---+
| 0 | 4 | | 1 | 5 | | 2 | 6 | | 3 | 7 |
+---+---+ +---+---+ +---+---+ +---+---+
| | | | | | | | | | | |
+---+---+ +---+---+ +---+---+ +---+---+
M1 M2 M3 M4
(6) 多体并行之同时启动(算读几次):内存总线要与一次并行读写的位宽一致。对于上面的例子,一次读取 4 个字。每一次读,在每一个模块中读取的位置是一致的。
例如:如果一个占 8 个存储单元的变量,存储在地址 1处,那么要读 3 次。
(7) 多体并行之轮流启动(算冲突):一次读一个体中的数据,4 个总线周期(小于等于存储周期)读完。
为什么可能发生冲突:一个模块在 1 个存储周期中,只能读 1 次。
访存地址 | 1001 | 1002 | 1003 | 1004 | 1008 | 1012 |
---|---|---|---|---|---|---|
模块号 | 1 | 2 | 3 | 4 | 0 | 0 |
冲突 | Y |
外存¶
机械磁盘地址结构
磁道号 | 磁头号 | 扇区号 |
---|---|---|
第几柱面 | 第几盘面 | 第几扇区 |
磁盘调度算法见操作系统。
高速缓存¶
一般是让算 cache line 中的 addr tag 长。
(1) 与内存地址之间的映射
a. 直接映射:直接取模
b. 全相联映射:可以放置在任意的 cache line,每次读写需要与所有 cache line 中的 addr tag 比较。
c. 组相联映射:将 cache line 分组,组内使用全相联映射,组间使用直接映射。
k 路组相联 = 每一组有 k 个比较器,即 k 个 cache line。假设缓存中共有 n 个 cache line,那么组数为 n/k。
物理地址中,低位为块内地址(取决于主存块的大小),中间位为组号(\(\log_2 n/k\) 位),高位为标记(剩余位)。
(2) 读写策略
- 读
- 命中时:直接读 cache
- 未命中时:根据替换算法调入 cache,并读取
- 写
- 命中时:
- Write Through:同时写 cache 和主存
- Write Back:只写 cache,当被替换时,根据 D 决定是否写回主存
- 未命中时:
- 写分配:写入主存,并将其调入 cache
- 非写分配:只写入主存
- 分配指的是是否分配 cache line
- 命中时:
(3) 替换算法(全/组相联时)
LRU,...
TLB¶
采取全相联,写回法。
TLB 维护 va 到 pa 的映射。
TLB 未命中时,需要访问页表,不再查询 cache。
当 TLB 未命中时,可能会发生缺页,需要把某页调入主存,然后替换 TLB 中的某行。
cache 使用的是 pa,因此:
Page miss 必然 TLB miss 必然 cache miss。
第四章 指令系统¶
ISA 设计¶
(1) 指令字长与字长之间的对齐
(2) 算可用的 opcode 数量:定长操作码、变长操作码(前缀码)
寻址方式¶
根据寻址目标分为指令寻址、数据寻址。
寻址方式:立即数寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址、PC-relative 寻址、基址寻址、变址寻址...
所谓间接:指令给出数据所在的内存地址,再从该地址中取出数据。
基址寻址:基地址寄存器 + 偏移量。基地址寄存器通常不变。
变址寻址:变址寄存器 + 偏移量。变址寄存器通常会变,而偏移量不变。
x86 汇编¶
cs:ip
当前正在执行的指令的地址。
函数入口:push bp
、mov bp, sp
。
函数出口:leave
、ret
。这等价于 mov sp, bp
、pop bp
、ret
。
算堆栈框架。
CISC/RISC¶
第五章 中央处理器¶
基本功能和结构¶
划分:CPU = 运算器 + 控制器。
寄存器组被拆分到了这两个部分中。其中:运算器包含 GPRs、PSW;控制器包含 IR、PC、MAR、MDR。
指令的执行过程¶
区分:机器周期(CPU 周期)、指令周期、存储周期、时钟周期。
指令周期 = 取值周期 + (间接寻址周期) + 执行周期 + 中断周期。这里等式右边的每一个部分被称为一个机器周期。
上面的划分是逻辑上的。
时钟周期:CPU 接入的外部时钟信号的周期。
根据时钟周期(例如,在一个时钟周期内只执行并执行完成一条指令),可以分为单周期 CPU、多周期 CPU、流水线 CPU、...
数据通路¶
注意一个没见过的元件:三态门,当其控制信号为 0,电路处于高阻态;为 1 时,电路导通。
总线:一个硬连线,需要注意总线冲突问题。
控制单元¶
控制单元分为硬连线和微控制器。
微控制器的本质是将一条指令进一步细分为多个微操作,这些微操作存储控制存储器中。指令译码时,跳转到对应的入口地址。
微指令编码:
直接编码:直接将所有微操作用 01 编码在微指令高位。
操作控制信号 | 下地址 |
---|---|
A1 A2 A3 ... | ... |
字段直接编码:将上面的控制信号字段划分为多个字段,互斥性微操作放在同一个字段中,相容性微操作放在不同字段中。每一个字段需要预留一个全零的编码表示什么都不做。
操作控制字段 1 | 操作控制字段 2 | ... | 下地址 |
---|---|---|---|
A1 A2 A3 ... | B1 B2 B3 ... | ... | ... |
字段间接编码:再套一层微控制器。
水平型微指令:向上面那样的编码方式。
垂直型微指令:一条微指令只能对应一个微操作,把上面的微操作按 A1 A2 A3 ... 拆分(以 muOP 识别)
异常和中断¶
(1) 异常 = exception:指令执行时,CPU 内部发生的。
(2) 中断 = interruption:指令执行时,CPU 外部发生的中断请求,又细分为:fault(执行时检测到的异常事件)、trap(例如单步调试)、abort(硬件错误)
流水线¶
(1) 性能指标:吞吐率 = 任务数 / 总耗时;加速比 = 单周期耗时 / 流水线耗时。
(2) 流水线 Hazzard:结构冲突、数据冒险(load-use,use-use)、控制冒险(B、J 型指令)
解决方案:数据冒险:Forwarding、Load-Use 中不得不插入 stall;控制冒险:分支预测、延迟槽。
多处理器系统¶
{S/M} I {S/M} D
I = instruction flow;D = data flow;S = single;M = multiple。
(1) SIMD:向量机
(2) MIMD:分为共享存储(多处理器系统)和分布式存储(多计算机系统)
多处理器系统中,根据是否通过统一的内存控制器,进一步划分为 UMA(统一内存访问)和 NUMA(非统一内存访问)。
NUMA 系统理论上可以实现无限的扩展,但实际上会受到总线带宽的限制。
(3) 硬件超线程:一个物理核心模拟出多个逻辑核心。
细粒度多线程:每个时钟周期发射某个线程中的指令。同一个时钟周期只能发射一个线程中的指令。
粗粒度多线程:仅当一个线程阻塞时,切换到另一个线程。
同时多线程:在一个时钟周期内,同时发射多个线程中的指令。
第六章 总线¶
总线分类¶
描述总线性能的参数:
总线时钟周期(一般为机器周期)、总线传输周期(一次完整的传输所用时间,又称总线周期)、总线工作频率(总线时钟周期的倒数)
(1) 同步/异步总线:总线上连接的设备有/没有统一的时钟
(2) 串行/并行总线:有一条/多条双向数据线
总线事务、总线定时¶
(1) 突发事务:传送一个地址,然后连续传送多个数据。
(2) 非突发事务:传送一个地址,然后传送一个数据。
(3) 同步定时:使用同一个时钟信号。
(4) 异步定时:使用专门的握手信号。根据请求和响应是否互锁分为不互锁、半互锁、全互锁。
不互锁:主设备发出请求信号后,过一段时间即可撤销;从设备发出响应信号后,过一段时间即可撤销。
半互锁:主设备发出请求信号后,必须等待收到从设备的响应信号后,主设备才能撤销请求信号。从设备发出响应信号后,过一段时间即可撤销。
全互锁:主设备发出请求信号后,必须等待收到从设备的响应信号后,主设备才能撤销请求信号。从设备发出响应信号后,必须等待主设备撤销请求信号后,从设备才能撤销响应信号。
I/O 系统¶
相关概念¶
(1) I/O 接口 = I/O 控制器
I/O控制器负责地址译码、设备选择、通信链路控制、数据缓冲、串并信号格式转换、传送控制信号
(2) I/O 端口 = I/O 接口中的寄存器
(3) I/O 编址:独立编址(使用专门的 IN
和 OUT
指令)、内存映射编址(使用内存地址访问 I/O 端口)
I/O 方式¶
(1) 程序中断
a. 轮询
b. 定时:算最小间隔,例如,外设准备好一个单位的数据所需要的时间
(2) 中断屏蔽字
每一个设备都对应一个中断屏蔽字,其中每一位表示该设备是否可以中断来自其他设备的中断
例如,处理优先级为 A > B > C > D 时,它们的中断屏蔽字为:
设备 | 中断屏蔽字 |
---|---|
A | 1111 |
B | 0111 |
C | 0011 |
D | 0001 |
(3) DMA 方式
DMA 控制器负责数据传输,CPU 仅负责初始化和结束。开始前和结束后通过中断通知 CPU。
DMA 控制器和 CPU 争夺访存总线,解决方案有:
a. 停止 CPU 访存:当有 DMA 请求,CPU 暂停访存
b. 周期挪用:单字传送,以周期为粒度:当 DMA 和 CPU 同时访存时,CPU 放弃访存周期;当 CPU 正在访存时,此时发生的 DMA 请求等待该周期结束后再访存。
c. 时分复用:每个访存周期在时间上被分为两部分,一部分给 CPU,一部分给 DMA