跳转至

计算机组成与体系结构

本文系统梳理了计算机组成与体系结构的核心内容,重点涵盖了计算机的基础概念、数据表示与运算、存储系统与层次结构、指令系统与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) 读写策略

    1. 命中时:直接读 cache
    2. 未命中时:根据替换算法调入 cache,并读取
    1. 命中时:
      • Write Through:同时写 cache 和主存
      • Write Back:只写 cache,当被替换时,根据 D 决定是否写回主存
    2. 未命中时:
      • 写分配:写入主存,并将其调入 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 bpmov bp, sp

函数出口:leaveret。这等价于 mov sp, bppop bpret

算堆栈框架。

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 编址:独立编址(使用专门的 INOUT 指令)、内存映射编址(使用内存地址访问 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