第 5 章 中央处理器
408 计算机组成原理第 5 章 中央处理器复习讲义,涵盖核心概念、重点考点与典型题型。
Last updated on
可以先用一句话抓住整章:
第 4 章告诉你“机器指令长什么样”,第 5 章告诉你“CPU 到底怎样把这条机器指令执行出来”。
整章主线是:
PC 给出指令地址
↓
从存储器取指令
↓
IR 保存指令
↓
控制器译码
↓
发出控制信号
↓
寄存器 / ALU / 主存之间传送数据
↓
完成运算、访存、写回
↓
检查异常和中断
↓
进入下一条指令而流水线是在这条主线之上继续问:
能不能让第1条指令执行时,
第2条同时译码,
第3条同时取指?答案就是:可以,这就是指令流水线。
一、本章考研重要程度
建议按下面的优先级复习。
| 重要程度 | 内容 | 要求 |
|---|---|---|
| ★★★★★ | 单总线数据通路 | 会分析数据流、微操作、控制信号 |
| ★★★★★ | 五段流水线 | 会画时空图、算周期 |
| ★★★★★ | 数据冒险、转发、阻塞 | 必须熟练 |
| ★★★★★ | 微程序控制器 | 会概念、会微指令编码计算 |
| ★★★★☆ | CPU 寄存器 | PC、IR、MAR、MDR 必须分清 |
| ★★★★☆ | 指令周期 | 指令周期、机器周期、时钟周期 |
| ★★★★☆ | 异常和中断 | 故障、自陷、终止、返回地址 |
| ★★★☆☆ | 硬布线控制器 | 与微程序控制器比较 |
| ★★★☆☆ | 超标量、动态流水线 | 理解基本思想 |
| ★★☆☆☆ | 多处理器、SMT、SMP | 概念辨析 |
二、5.1 CPU 的功能和基本结构
1. CPU 到底干什么
资料将 CPU 的基本功能概括为:
- 取指令并译码
- 更新 PC
- 执行算术与逻辑运算
- 取操作数或写结果
- 处理异常和中断
- 进行时序控制
也就是说,CPU 不只是“算数”。
更准确地说:
CPU = 数据通路 + 控制器 + 一组关键寄存器 + 异常/中断处理机构。
其中:
- 数据通路负责“干活”;
- 控制器负责“指挥”;
- 寄存器负责“暂存状态和数据”。
资料中的 CPU 基本结构包括 PC、IR、MAR、MDR、ALU、GPRs、控制单元 CU、中断机构等。
三、CPU 中最重要的几个寄存器
这是选择题高频点。
1. PC——程序计数器
PC 保存的是:
下一条将要取出的指令地址。
正常顺序执行:
PC → 取指
PC ← PC + 指令长度例如 MIPS 一条指令固定 4B,则通常:
如果执行跳转、分支、中断:
PC ← 目标地址所以 PC 决定的是:
“下一条指令从哪里取?”
2. IR——指令寄存器
IR 保存:
当前正在执行的指令。
流程是:
主存 → MDR → IR然后控制器从 IR 中取出:
- 操作码;
- 寄存器编号;
- 地址码;
- 立即数;
进行译码。
因此:
PC:地址
IR:指令本身这是必须分清的。
3. MAR——存储器地址寄存器
MAR 保存:
当前要访问的主存地址。
无论是:
- 取指;
- 读数据;
- 写数据;
只要访问主存,就要告诉主存:
我要访问哪个地址?这个地址放 MAR。
4. MDR——存储器数据寄存器
MDR 保存:
CPU 与主存之间正在交换的数据。
读存储器:
MAR → 地址
主存 → MDR写存储器:
MAR → 地址
MDR → 主存所以可以这样记:
MAR:地址
MDR:数据5. 通用寄存器 GPR
用于保存:
- 操作数;
- 运算结果;
- 地址;
- 临时变量。
例如:
add r1,r2,r3本质上:
R[r2] → ALU
R[r3] → ALU
ALU结果 → R[r1]6. PSW / 状态寄存器
保存 CPU 当前运行状态,例如:
- 零标志 ZF;
- 符号标志 SF;
- 进位标志 CF;
- 溢出标志 OF;
- 中断允许位;
- CPU 工作模式等。
条件转移经常依赖它。
例如:
sub r1,r2
jz label第二条指令本质上要检查:
ZF 是否为 1四、一个特别容易问的问题:指令和数据都是 0/1,CPU 怎么区分?
这是资料明确要求思考的问题。
答案不是:
指令有某种特殊二进制格式,所以一眼能看出来。
并不是。
在冯·诺依曼结构里:
指令和数据在存储器中的形式本质上没有区别。
CPU 主要根据当前执行阶段和访问目的区分。
例如:
取指阶段
PC → MAR
主存 → MDR
MDR → IR此时读出的内容被放进 IR:
CPU 就把它当“指令”。
执行阶段取操作数
有效地址 → MAR
主存 → MDR此时 MDR 中的内容被送给 ALU 或寄存器:
CPU 就把它当“数据”。
所以:
不是数据本身告诉 CPU“我是指令”,而是 CPU 当前怎么使用它决定它是什么。
五、5.2 指令执行过程
1. 一条指令的一般执行过程
资料将其概括为:
取指
↓
译码
↓
取操作数
↓
执行
↓
写回
↓
检查异常/中断分支指令还可能修改 PC。
现代教材中常进一步划分成经典五阶段:
IF → ID → EX → MEM → WB分别为:
| 阶段 | 含义 |
|---|---|
| IF | Instruction Fetch,取指 |
| ID | Instruction Decode,译码、读寄存器 |
| EX | Execute,ALU 执行或计算地址 |
| MEM | Memory,访存 |
| WB | Write Back,写回 |
注意:
不是所有指令五阶段都真正干活。
例如普通 ADD:
IF → ID → EX → MEM(空) → WBSTORE:
IF → ID → EX → MEM → WB(空)六、指令周期、机器周期、时钟周期
这个一定要搞清层级。
从大到小:
指令周期
↓
机器周期
↓
时钟周期 / 节拍1. 指令周期
CPU 执行一条完整机器指令所需要的全部时间。
例如:
取指周期
+
间址周期
+
执行周期
+
中断周期共同组成一条指令的指令周期。
但:
不同指令不一定包含所有机器周期。
例如寄存器加法通常不需要取操作数主存周期。
2. 机器周期
完成一个相对完整的基本任务所需要的时间。
例如:
- 取指;
- 访存;
- 执行;
- 中断响应。
3. 时钟周期
CPU 最基本的同步单位。
也就是:
其中:
- :时钟周期;
- :CPU 主频。
现代处理器里,“机器周期”的概念逐渐弱化,更常直接用若干时钟周期描述指令执行时间。资料也指出,不同指令可能具有不同的 CPI。
七、单周期、多周期、流水线处理器
这是非常重要的一组比较。
1. 单周期 CPU
每条指令都在一个时钟周期完成。
因此:
但问题是:
时钟周期必须长到足够让最慢的那条指令执行完成。
假设:
ADD:400 ps
BEQ:450 ps
LW:800 ps那整个 CPU 的时钟周期只能至少:
于是 ADD 明明 400 ps 就能干完,还必须等到 800 ps。
所以:
CPI 看起来漂亮,但时钟周期很长。
2. 多周期 CPU
把指令拆成:
取指 → 译码 → EX → MEM → WB每个阶段一个周期。
于是:
- ADD 可能 4 周期;
- LW 可能 5 周期;
- STORE 可能 4 周期。
优点:
不同指令需要多少周期就用多少,不必全部迁就最慢指令。
但:
不同指令之间仍然不能重叠执行。
3. 流水线 CPU
进一步让:
I1:EX
I2:ID
I3:IF同时发生。
于是多条指令重叠执行。
理想情况下:
注意一个极容易错的判断:
流水线提高的主要是吞吐率,而不是单条指令的延迟。
资料明确强调了这一点。
八、5.3 数据通路——本章第一大重点
1. 什么叫数据通路?
一句话:
CPU 内部,数据从一个部件流向另一个部件的路径,就叫数据通路。
例如执行:
add r3,r1,r2本质上:
r1 ─┐
├→ ALU → r3
r2 ─┘控制器负责:
打开 r1 输出
打开 r2 输出
选择 ALU 加法
打开 r3 写使能所以:
数据通路回答“数据怎么走”。
控制器回答“谁在什么时候允许数据走”。
九、数据通路中的两类基本元件
资料将元件分成:
1. 组合逻辑元件
没有存储能力。
输出只由当前输入决定。
例如:
- ALU;
- 加法器;
- MUX;
- 译码器;
- 三态门。
MUX 多路选择器
假设有 8 路输入,要选择其中 1 路:
需要:
位选择信号。
一般:
2. 时序逻辑元件
具有状态保存能力。
例如:
- PC;
- IR;
- MAR;
- MDR;
- 通用寄存器;
- 流水段寄存器。
资料给出了数据通路时钟周期下界:
本质上就是:
前一级寄存器输出稳定
+
组合逻辑运算
+
后一级寄存器建立时间必须在下一个时钟边沿前完成。
十、总线式数据通路和专用数据通路
资料把数据通路按连接方式分成:
总线式
R1
R2 ── 公共总线 ── ALU
R3
PC
MDR优点:
- 线路少;
- 成本低;
- 扩展方便。
缺点:
总线一次只能承载一组数据。
专用数据通路
R1 ─────┐
├→ ALU
R2 ─────┘
│
↓
R3有专用线路。
优点:
- 可以并行;
- 速度快。
缺点:
- 连线多;
- 电路复杂;
- 成本高。
资料对二者的比较也明确指出:专用数据通路吞吐更高,而总线式结构更简单、扩展更方便。
十一、单总线数据通路——综合题核心
单总线最重要的规则:
同一时刻只能有一个部件向总线输出。
例如不能同时:
R1out = 1
R2out = 1否则两个寄存器同时驱动总线,发生冲突。
但可以:
R1out
Yin
MARin意思是:
R1 → 总线 → Y
→ MAR一个源可以送给多个目的部件。
十二、为什么单总线 ALU 前面需要 Y,后面需要 Z?
这是很多人第一次学最难理解的地方。
假设要:
ALU 要同时拿到两个输入。
但单总线只有一条。
不能同时:
R1 → 总线
R2 → 总线怎么办?
第一步
R1 → 总线 → Y先保存一个操作数。
第二步
R2 → 总线 → ALU
Y ─────────→ ALU于是 ALU 两个输入都有了。
计算:
结果先进入 Z:
ALU → Z第三步
Z → 总线 → R3于是完整过程为:
R1 → Y
R2 + Y → Z
Z → R3资料明确解释:由于 ALU 是没有存储能力的组合逻辑部件,单总线结构必须使用 Y 保存一个操作数,并使用 Z 保存 ALU 结果。
十三、单总线题到底怎么做?
以后见到这种图,固定按照下面的方法。
假设:
ADD rd,rs功能:
第一步:先写“逻辑数据流”
rs → Y
rd + Y → Z
Z → rd第二步:再翻译成控制信号
例如:
C1:
GPRout(rs), Yin
C2:
GPRout(rd), ALUadd, Zin
C3:
Zout, GPRin(rd)不要一上来硬背控制信号。
先问:
数据要从哪里到哪里?
再根据线路图决定打开哪些门。
十四、取指过程也要会
资料中的单总线示例是:
PC → MAR
MEM[MAR] → MDR
MDR → IR若暂不考虑 PC 自增,可以写成:
C1:PCout,MARin
C2~C6:Read,MDRin
C7:MDRout,IRin资料中的例子假设一次主存读取需要 5 个时钟周期,因此中间要等待多个周期。
可以发现:
PC、MAR、MDR、IR 的真正含义,一到数据通路题里就全部串起来了。
十五、专用数据通路中的几个高频控制信号
这一部分非常适合出选择题。
例如 MIPS 风格数据通路。
RegDst
决定“写哪个寄存器”。
R 型:
add rd,rs,rt写 Rd。
I 型:
addi rt,rs,imm写 Rt。
因此:
RegDst = 1 → Rd
RegDst = 0 → RtALUSrc
决定 ALU 第二个操作数来自:
寄存器 Rt还是:
扩展后的立即数即:
ALUSrc = 0 → Rt
ALUSrc = 1 → immediateMemtoReg
决定写回寄存器的数据来自:
ALU结果还是:
存储器数据所以 LOAD:
MemtoReg = 1普通 ADD:
MemtoReg = 0资料对这些选择器和 LOAD/STORE 数据通路有完整说明。
十六、5.4 控制器——CPU 的“指挥中心”
控制器本质上做的是:
根据“当前是什么指令 + 当前到哪个时钟节拍 + 当前状态”,产生控制信号。
例如:
ADD R3,R1,R2控制器可能依次产生:
R1out
Yin
R2out
ALUadd
Zin
Zout
R3in也就是说:
机器指令最终必须被拆成很多非常细小的硬件动作。
这种细小动作叫:
微操作。
控制微操作发生的信号叫:
微命令。
十七、硬布线控制器
硬布线控制器直接使用:
- 操作码译码结果;
- 时序信号;
- 状态标志;
通过组合逻辑产生控制信号。
可以抽象成:
例如某控制信号:
意思是:
ADD 指令第3拍
或
SUB 指令第4拍都需要产生这个控制信号。
优点
快。
因为直接经过逻辑电路。
缺点
难改。
加一条指令可能需要重新设计逻辑电路。
所以通常:
RISC → 更适合硬布线资料也明确将其概括为“速度快、灵活性差”。
十八、微程序控制器——本章第二大难点
这一部分先把层级关系搞清楚。
程序
↓
机器指令
↓
微程序
↓
微指令
↓
微命令
↓
微操作例如:
ADD R3,R1,R2这是:
机器指令。
为了执行它,内部可能运行一个 ADD 微程序。
微程序包含:
微指令1
微指令2
微指令3
...每条微指令又产生:
R1out
Yin
ALUadd
Zin
...这些就是微命令。
十九、几个必须区分的概念
微操作
实际发生的硬件动作。
例如:
PC → MAR微命令
控制这个微操作发生的控制信号。
例如:
PCout
MARin微指令
一组同时或按规定产生的微命令。
微程序
若干微指令组成。
通常:
一条机器指令对应一个微程序。
但取指、间址、中断等公共操作可以使用公共微程序。
二十、微程序控制器中的几个重要寄存器
CM——控制存储器
存:
微程序 / 微指令。
注意:
主存:机器程序和数据
控制存储器 CM:微程序这两个不要混。
μPC / CMAR
微程序计数器。
存:
下一条微指令地址。
对应关系:
PC → 机器指令地址
μPC → 微指令地址μIR / CMDR
保存:
当前微指令。
对应:
IR → 当前机器指令
μIR → 当前微指令这四个非常容易混。
二十一、微程序执行过程
固定记:
取指微程序
↓
机器指令进入 IR
↓
操作码 → 微地址形成部件
↓
得到该机器指令的微程序入口
↓
μPC
↓
CM 取微指令
↓
μIR
↓
产生微命令
↓
执行微操作
↓
下一条微指令当前机器指令执行结束:
再次进入公共取指微程序资料正是按这个过程描述微程序控制器工作的。
二十二、微指令编码——很适合计算题
假设有 20 个控制信号。
1. 直接编码
一个微命令对应一位。
那么需要:
优点:
不需要译码,快。
缺点:
微指令很长。
2. 字段直接编码
把互斥的微命令放在一个字段里。
假设某组有 7 个互斥微命令,还要表示“不执行任何操作”。
总状态数:
所需位数:
因此通用公式:
其中 是这一组互斥微命令数。
为什么加 1?
因为需要:
“本组不发任何微命令”状态。
这是很常见的陷阱。
二十三、水平型与垂直型微指令
水平型
一条微指令可以同时控制多个微操作。
例如:
PCout = 1
MARin = 1
Read = 1特点:
- 字长长;
- 并行度高;
- 微程序短;
- 执行快。
垂直型
更像普通机器指令:
微操作码 + 地址通常一条微指令描述较少甚至一个基本微操作。
特点:
- 字长短;
- 并行度低;
- 微程序长;
- 执行慢;
- 编程方便。
资料对二者的总结也是:水平型并行能力强、效率高但字长较长;垂直型字长短但执行微程序更长。
二十四、硬布线 vs 微程序
这个表建议直接记住。
| 项目 | 硬布线 | 微程序 |
|---|---|---|
| 控制信号 | 逻辑电路直接产生 | 微指令产生 |
| 速度 | 快 | 较慢 |
| 灵活性 | 差 | 好 |
| 修改 | 困难 | 容易 |
| 结构 | 较复杂 | 规整 |
| 常见倾向 | RISC | CISC |
一句话:
硬布线 = 用电路写控制逻辑。
微程序 = 用“微代码”写控制逻辑。
二十五、5.5 异常与中断
这是“组成原理 + 操作系统”的交叉考点。
最核心的区分:
异常
来自:
CPU 内部、当前指令执行过程。
所以通常是同步事件。
例如:
- 除零;
- 缺页;
- 非法指令;
- 溢出;
- 系统调用。
中断
通常来自:
CPU 外部。
例如:
- 键盘;
- 网卡;
- 磁盘;
- 定时器。
具有异步性。
资料对二者也是这样区分的。
二十六、异常的三种类型
这是重点。
1. Fault——故障
特点:
当前指令还没有成功执行完。
如果能修复,就:
回去重新执行当前指令。
典型:
缺页异常
CPU 访问某页:
页不在内存→ 缺页异常
OS:
磁盘 → 内存
更新页表然后:
重新执行刚才那条访存指令。
所以 Fault 的返回地址通常指向:
发生故障的当前指令。
2. Trap——自陷
特点:
指令是有意引发异常的。
典型:
- 系统调用;
- 断点;
- 单步调试。
比如:
syscall这条指令本身已经完成“请求进入内核”的作用。
处理后通常:
从下一条指令继续。
所以返回地址是:
自陷指令的下一条。
资料也明确指出,自陷处理后从下一条指令继续执行。
3. Abort——终止
严重到无法恢复。
例如:
- 严重硬件故障;
- 总线错误; -存储器校验严重错误。
通常:
当前程序无法正常恢复。
二十七、异常/中断返回地址怎么判断?
这是非常重要的做题规则。
先问一句:
这条指令需要重新执行吗?
如果需要重新执行
保存:
当前指令地址。
例如:
Fault
缺页如果不用重新执行
保存:
下一条指令地址。
例如:
外部中断
Trap资料对中断、Fault、自陷的断点位置也有明确区分。
二十八、中断什么时候响应?
普通外部中断通常满足:
- 有中断请求;
- CPU 开中断;
- 当前指令执行完成;
- 没有更高优先级事件。
所以:
I/O 中断通常是在一条指令执行完成后响应。
不是执行到一半随便切走。
异常则不同。
异常可能:
在当前指令执行过程中检测出来。
资料明确将“当前指令已经执行完毕”作为普通中断响应的重要条件。
二十九、中断隐指令——非常高频
CPU 决定响应中断后,硬件自动完成一系列动作。
称为:
中断隐指令。
注意:
它不是 ISA 中真正可以写出来的一条机器指令。
主要完成:
关中断
↓
保存断点
↓
找到中断服务程序入口
↓
PC ← 中断服务程序入口资料称其硬件自动阶段为“关中断 → 保存断点 → 中断服务程序寻址”。
三十、“保存断点”和“保存现场”不是一回事
非常容易错。
保存断点
为了以后知道:
返回哪里。
主要保存 PC 等。
一般:
硬件完成。
保存现场
保存:
- 通用寄存器;
- 状态寄存器;
- 其他会被中断服务程序修改的内容。
一般:
中断服务程序用软件指令完成。
所以:
中断响应阶段:
保存断点
中断服务程序:
保存现场不要混。
三十一、完整中断处理过程
资料给出的典型嵌套中断流程非常值得背:
硬件:
关中断
↓
保存断点
↓
中断服务程序寻址
软件:
保存现场和屏蔽字
↓
开中断
↓
执行服务程序
↓
关中断
↓
恢复现场和屏蔽字
↓
开中断
↓
中断返回为什么中间开中断?
为了:
允许更高级中断打断当前中断服务程序。
为什么恢复现场前又关中断?
因为:
恢复过程中不能被打断,否则现场可能被破坏。
三十二、5.6 指令流水线——本章第一大考点
流水线的核心比喻就是工厂流水线。
假设一条指令要经过:
IF
ID
EX
MEM
WB不流水时:
I1: IF ID EX MEM WB
I2: IF ID EX MEM WB
I3: IF...流水后:
周期 1 2 3 4 5 6 7
I1 IF ID EX MEM WB
I2 IF ID EX MEM WB
I3 IF ID EX MEM WB到了流水线填满以后:
每个周期都有一条指令完成。
三十三、流水线最重要的一个认识
流水线主要提高吞吐率,不一定降低单条指令执行时间。
甚至:
加入流水段寄存器后,单条指令总延迟还可能略微增加。
但是假如有几百万条指令:
总体性能会显著提升。
三十四、流水线时钟周期怎么算?
若每个流水段延迟分别:
IF 180 ps
ID 130 ps
EX 200 ps
MEM 170 ps
WB 100 ps那么时钟周期至少受最慢段限制:
如果流水段寄存器额外延迟 20 ps:
这也是资料中的高频考点。
三十五、k 段流水线执行 n 条指令
理想情况下:
第一条需要 个周期。
以后每周期完成 1 条。
因此:
这是整个流水线计算最核心的公式。
例如:
- 5 段流水线;
- 100 条指令;
- 周期 2ns。
则:
三十六、流水线吞吐率
资料给出的定义:
代入:
当任务很多:
则:
也就是说:
流水线填满以后,理论上每个周期输出一个结果。
三十七、流水线加速比
如果非流水方式每条指令依次经过 个等长阶段,则:
流水:
因此加速比:
即:
当:
则:
所以理想情况下:
k 段流水线最大加速比约为 k。
注意,这是理想极限。
现实中有:
- 流水段不均衡;
- 冒险;
- Cache miss;
- 分支;
- 异常;
所以达不到。
三十八、流水线为什么会出问题?
三大冒险:
结构冒险
数据冒险
控制冒险必须全部掌握。
三十九、结构冒险
含义:
两条指令同一时刻想使用同一个硬件资源。
例如只有一个统一存储器:
I1:MEM 阶段读数据
I4:IF 阶段取指两个同时访问一个存储器。
冲突。
解决:
- 等待;
- 增加硬件;
- 指令 Cache 和数据 Cache 分离。
这也是为什么经典五段流水线常使用:
I-Cache
D-Cache四十、数据冒险——最重要
例如:
add r1,r2,r3
sub r4,r1,r5第二条要读取 r1。
但第一条还没来得及写 r1。
于是:
sub 读到了旧 r1这就是数据冒险。
四十一、RAW、WAR、WAW
设:
R = Read
W = WriteRAW
Read After Write。
I1:写 R1
I2:读 R1I2 必须等 I1。
这是:
真数据相关。
经典五段顺序流水线最重要的就是它。
WAR
Write After Read。
I1:读 R1
I2:写 R1如果 I2 过早写,会破坏 I1 应该读取的旧值。
WAW
Write After Write。
I1:写 R1
I2:也写 R1必须保持正确写入顺序。
在普通五段、顺序发射、顺序完成流水线中:
主要出现 RAW。
WAR、WAW 更多见于乱序执行体系。
四十二、解决 RAW:方法一——停顿
例如:
add r1,r2,r3
sub r4,r1,r5如果没有转发:
add: IF ID EX MEM WB
sub: IF ID -- -- EX MEM WB必须等 add 把结果真正写回寄存器堆。
题库中就有典型题:对于五段式流水线,如果前半周期写寄存器、后半周期读寄存器,并且没有转发,需要根据生产者的 WB 和消费者的 ID 时刻计算插入 nop 数量。资料中的对应题结果为至少插入 2 条 nop。
四十三、解决 RAW:方法二——转发 Forwarding
关键思想:
结果已经算出来了,就没必要非等它写回寄存器再读一次。
例如:
add:
EX 阶段结束 → 结果已经产生sub 下一周期正好进入 EX。
那么直接:
EX/MEM寄存器
↓
ALU输入即可。
流程:
add EX → Forward → sub EX资料明确指出,相邻普通 ALU 运算的 RAW 可以通过转发解决。
四十四、最重要的特殊情况:load-use
看:
lw r1,0(r2)
add r3,r1,r4LW 的 r1 什么时候产生?
不是 EX。
EX 只计算:
R[r2] + offset真正从存储器读出数据要到:
MEM 阶段结束。
而紧跟的 ADD:
EX 阶段已经需要 r1。
于是时间来不及。
即使有 forwarding:
仍然至少要停 1 个周期。
所以经典结论:
普通 ALU → ALU:转发往往可直接解决。
LOAD → 紧随其后的使用者:即使有转发,通常仍需阻塞 1 个周期。
资料对此专门称为 load-use 数据冒险。
这个一定背。
四十五、控制冒险
典型:
beq r1,r2,LCPU 在取后面的指令时:
还不知道到底跳不跳。
于是可能已经取了:
PC+4
PC+8后来发现:
应该跳到 L。
那前面取错的指令就必须丢掉。
叫:
flush / 冲刷流水线。
四十六、控制冒险的解决
常见:
1. 停顿
等分支结果出来。
简单,但慢。
2. 尽早计算分支条件
比如把判断从 EX 提前。
这样少浪费几个周期。
3. 分支预测
预测:
跳或者:
不跳预测正确:
基本不损失性能。
预测失败:
清空错误路径。
现代 CPU 广泛使用动态分支预测。
四十七、流水线题的固定做法
遇到流水线时空图,不要凭感觉。
按照 4 步:
第一步:写每条指令真正产生结果的阶段
例如:
ADD:
EX 结束产生 ALU 结果
LW:
MEM 结束产生数据第二步:写后继指令什么时候需要数据
通常:
ALU 指令:
EX 开始前需要操作数第三步:看有没有 forwarding
没有:
必须等 WB。
有:
看 EX/MEM 或 MEM/WB 是否来得及转发。
第四步:判断是否插 bubble
不要死背“停两拍”“停一拍”。
问:
数据产生时刻 <= 数据需要时刻吗?
这才是真正的方法。
四十八、高级流水线
1. 超标量 Superscalar
普通流水线:
每周期最多发射 1 条超标量:
每周期可以发射多条例如 4 发射 CPU:
Cycle 1:
I1 I2 I3 I4要求处理器拥有:
- 多个执行单元;
- 相关性检测;
- 调度机构。
所以理想 CPI 甚至可以:
例如平均每周期执行 2 条:
四十九、动态流水线 / 动态调度
顺序程序:
I1
I2
I3
I4不代表 CPU 内部必须严格按这个顺序完成所有执行。
例如:
I1 等待 Cache
I2 依赖 I1
I3 与 I1 无关CPU 可以先执行 I3。
这就是:
乱序执行。
核心目的:
找到更多指令级并行性。
五十、VLIW——超长指令字
与超标量不同:
超标量
主要由:
硬件动态找并行。
VLIW
主要由:
编译器静态找并行。
然后把多条操作打包成一个很长的指令字。
资料把 VLIW 描述为一种静态多发射技术。
五十一、5.7 多处理器——理解为主
这一部分总体考频低于流水线和数据通路。
五十二、SISD、SIMD、MIMD
可以从“指令流”和“数据流”理解。
SISD
Single Instruction Single Data。
一个指令流
一个数据流传统单核标量 CPU。
SIMD
Single Instruction Multiple Data。
一条指令
同时处理多个数据例如向量:
A = [1,2,3,4]
B = [5,6,7,8]一条向量加:
A+B同时做:
1+5
2+6
3+7
4+8属于:
数据级并行。
MIMD
Multiple Instruction Multiple Data。
多个处理器:
Core 1:执行程序 A
Core 2:执行程序 B
Core 3:执行程序 C各自执行不同指令、处理不同数据。
属于更普遍的:
线程级 / 任务级并行。
资料也特别强调:SIMD 偏数据级并行,MIMD 可支持线程级或任务级并行。
五十三、向量处理器和多核不要混
向量:
一个指令操作很多数据。
多核:
多个核分别执行指令流。
例如:
向量:
一个人拿一根长杆,同时推4块石头。
多核:
4个人分别推4块石头。本质完全不同。
五十四、硬件多线程
普通操作系统线程切换:
保存寄存器
↓
保存 PC
↓
恢复另一个线程寄存器
↓
恢复 PC开销比较大。
硬件多线程:
CPU 内部直接保留多个线程的硬件上下文。
例如:
线程A:
PC_A
Regs_A
线程B:
PC_B
Regs_B切线程不用把全部状态先写回内存。
资料将硬件多线程分成三种。
五十五、细粒度多线程
每个周期换一次线程:
周期1:A
周期2:B
周期3:C
周期4:A优势:
一个线程遇到等待,其他线程补上。
五十六、粗粒度多线程
平时一直执行 A:
A A A A A直到 A 出现:
Cache miss才换 B:
B B B B五十七、SMT
Simultaneous Multithreading。
同一个周期:
线程A 指令1
线程A 指令2
线程B 指令1可以同时发射。
Intel Hyper-Threading 就属于典型 SMT。
核心区别:
粗/细粒度多线程主要是在不同周期换线程。
SMT 可以在同一个周期混合多个线程的指令。
资料也强调 SMT 同时利用指令级并行和线程级并行。
五十八、多核处理器
多核就是:
一块 CPU 芯片里集成多个真正的 CPU 核心。
例如:
Core 0
Core 1
Core 2
Core 3每个核通常有:
- 自己的寄存器;
- PC;
- ALU;
- L1 Cache;
部分高级 Cache 可能共享。
真正的多核可以:
多个线程物理上同时执行。
这与单核的时间片并发不同。
五十九、SMP、UMA、NUMA
SMP:
多个处理器共享一个物理地址空间。
所有 CPU 都能通过普通 LOAD/STORE 访问共享内存。
进一步:
UMA
Uniform Memory Access。
所有 CPU 访问不同内存:
延迟基本一致。
NUMA
Non-Uniform Memory Access。
CPU 访问:
自己的本地内存比较快。
访问:
别的 CPU 附近的内存比较慢。
所以:
“共享地址空间”不代表“访问所有地址延迟都一样”。
资料也按 UMA 和 NUMA 对 SMP 做了这个区分。
六十、本章最容易混淆的概念
最后把最常错的东西放一起。
| 容易混淆 | 正确理解 |
|---|---|
| PC | 下一条待取指令地址 |
| IR | 当前指令 |
| MAR | 主存地址 |
| MDR | 主存交换数据 |
| 指令周期 | 完成一条机器指令 |
| 时钟周期 | CPU 最基本时序单位 |
| 微操作 | 真正的硬件动作 |
| 微命令 | 控制微操作的信号 |
| 微指令 | 一组微命令 |
| 微程序 | 一组微指令 |
| 硬布线 | 控制信号由逻辑电路产生 |
| 微程序 | 控制信号由微指令产生 |
| Fault | 通常重新执行当前指令 |
| Trap | 通常从下一条继续 |
| 中断 | 一般在指令边界响应 |
| 保存断点 | 保存返回地址,通常硬件 |
| 保存现场 | 保存寄存器等,通常软件 |
| 流水线 | 主要提高吞吐率 |
| 转发 | 不等 WB,直接用中间结果 |
| load-use | 有转发通常仍需停 1 拍 |
| SIMD | 一条指令多个数据 |
| 多核/MIMD | 多个独立指令流 |
| SMT | 一个核心同时执行多个线程的指令 |
六十一、考场上最值得记住的 8 条结论
-
PC 放地址,IR 放指令,MAR 放访存地址,MDR 放访存数据。
-
单总线同一时刻只能有一个部件向总线输出,但可以有多个部件同时从总线接收。
-
单总线 ALU 通常需要 Y 保存一个输入,Z 保存输出。
-
硬布线快但难修改;微程序慢一些但灵活。
-
Fault 通常回到当前指令;Trap 和外中断通常回到下一条指令。
-
流水线提高的是吞吐率,不意味着一条指令本身变快。
-
普通 ALU-ALU RAW 可通过 forwarding 消除;经典 load-use 即使有转发通常仍需停 1 拍。
-
理想 k 段流水线执行 n 个任务:
并且:
最后把整章压缩成一张逻辑图
第5章 CPU
│
┌──────────────┼──────────────┐
│ │ │
数据通路 控制器 异常/中断
│ │ │
寄存器、ALU 硬布线/微程序 Fault/Trap
总线、MUX 微指令/微程序 中断响应
│
▼
指令执行
│
IF → ID → EX → MEM → WB
│
▼
流水线
│
┌──────┼─────────┐
│ │ │
结构冒险 数据冒险 控制冒险
│
RAW / forwarding
│
load-use
│
▼
超标量/乱序/SMT
│
▼
SIMD / MIMD / 多核 / SMP如果以408 应试为目标,第 5 章真正要做到“看见题就能做”的顺序是:
1 PC/IR/MAR/MDR → 2 指令周期 → 3 单总线微操作 → 4 微程序控制器 → 5 五段流水线 → 6 RAW/转发/load-use → 7 中断异常。
其中 3、4、5、6 是这章最值得反复做题的四块。题库也确实集中出现了 CPU 部件判断、数据相关与 nop 插入、流水线时钟周期等类型。