目录
一、引言:为什么要学习计算机体系结构
计算机体系结构(Computer Architecture)是计算机科学的核心基础学科,它研究计算机系统的设计理念、组织结构和工作原理。从冯·诺依曼提出"存储程序"概念至今,计算机体系结构经历了从单处理器到多核、从集中式到分布式的深刻演变。
对于软考考生而言,计算机硬件与体系结构是系统架构设计师、网络工程师、软件设计师等考试的必考内容,在上午选择题中占比约 8-15 分,同时也是下午案例分析题的重要背景知识。本章内容涉及大量计算题(流水线加速比、Cache 命中率、虚拟地址转换、RAID 容量),是拉开分数差距的关键。
1. 计算机组成:冯·诺依曼结构、CPU 结构、指令周期
2. 指令系统:CISC/RISC、寻址方式、指令流水线
3. 存储系统:存储层次、Cache 映射、虚拟内存
4. 输入输出:总线结构、I/O 控制方式、DMA
5. 多处理机:SMP、NUMA、Cache 一致性协议
6. 外存储:磁盘结构、RAID 级别与计算
· 计算题务必手算:流水线、Cache、地址转换、RAID 是高频计算题,光看公式没用,必须动手算 5 道以上
· 对比表格反复看:CISC vs RISC、三种 Cache 映射、五种 I/O 方式、RAID 各级别,对比记忆效率最高
· 理解优于背诵:例如"为什么要有 Cache?"——从"局部性原理"出发理解整个存储层次
二、计算机系统组成总览
一个完整的计算机系统由硬件系统和软件系统两大部分组成。硬件是物质基础,软件是灵魂,二者缺一不可。本章主要聚焦硬件系统的组织结构。
2.1 冯·诺依曼架构 vs 哈佛架构
现代计算机的两大基础架构流派分别是冯·诺依曼(Von Neumann)架构和哈佛(Harvard)架构,二者最核心的区别在于"数据和指令是否共享同一存储空间"。
· 不要混淆:现代高性能 CPU(如 x86/ARM)外部采用冯·诺依曼结构(统一主存),但内部 Cache 采用哈佛结构(L1 指令 Cache 与 L1 数据 Cache 分离),这种叫"改进型哈佛架构"
· DSP、单片机(如 8051、AVR)是典型的纯哈佛架构
2.2 计算机硬件五大基本部件
冯·诺依曼架构规定了计算机的五大基本组成部件:运算器、控制器、存储器、输入设备、输出设备。其中运算器+控制器 = CPU(中央处理器)。
· 运算器(ALU):执行算术运算(加减乘除)和逻辑运算(与或非异或)
· 控制器(CU):从内存取指令、译码、发出控制信号,协调各部件工作
· 存储器:内存+外存,存储程序和数据
· 输入设备:键盘、鼠标、扫描仪(将信息→计算机可识别格式)
· 输出设备:显示器、打印机(将结果→人可识别格式)
三、CPU 与指令系统
3.1 CPU 内部结构
CPU(Central Processing Unit,中央处理器)是计算机的"大脑",由运算器、控制器、寄存器组和内部总线构成。现代 CPU 还集成了 Cache(高速缓存)、MMU(内存管理单元)等部件。
· PC(程序计数器):存放下一条要取的指令地址,取指后自动递增,软考计算题高频
· IR(指令寄存器):存放当前正在执行的指令,从内存取出后暂存
· AR(地址寄存器):暂存要访问的内存单元地址
· DR(数据寄存器):暂存从内存读出/要写入的数据
· PSW(程序状态字):存放标志位(溢出OF、零ZF、符号SF、进位CF等)
· ACC(累加器):ALU 运算时存放操作数和中间结果
3.2 指令执行周期
一条指令从取出到执行完毕,需要经过若干阶段,这就是指令周期。经典的 5 阶段指令周期是理解流水线技术的基础。
· 指令周期:取出并执行一条指令的时间,不同指令长度可能不同
· CPU周期(机器周期):通常 = 从内存读取一条指令的最短时间,1指令周期 = N 个CPU周期
· 时钟周期(T周期/节拍):CPU 主频的倒数,最小时间单位,1CPU周期 = M 个时钟周期
· 关系:T指令 = N × T机器 = N × M × T时钟
3.3 CISC vs RISC 指令集架构
CISC(Complex Instruction Set Computer,复杂指令集)和 RISC(Reduced Instruction Set Computer,精简指令集)是 CPU 指令系统设计的两大哲学流派,也是软考高频对比考点。
| 对比维度 | CISC(复杂指令集) | RISC(精简指令集) |
|---|---|---|
| 代表架构 | Intel x86、AMD x86-64、VAX | ARM、MIPS、RISC-V、PowerPC、SPARC |
| 指令数量 | 200~1500 条,多而复杂 | <100 条,少而精简 |
| 指令长度 | 不固定,1~15 字节(x86) | 固定长度,如 32 位 ARM / 16 位 Thumb |
| 寻址方式 | 多(10+ 种),灵活复杂 | 少(3~5 种),简单规整 |
| 访存限制 | 算术指令可直接访问内存 | Load/Store 架构,仅 L/S 指令可访存 |
| 通用寄存器 | 少(x86 8个/16个) | 多(32个,MIPS/RISC-V) |
| 控制实现 | 微程序控制为主(灵活慢) | 硬布线逻辑为主(速度快) |
| 流水线 | 实现复杂,早期不适合流水 | 天然适合流水线、超标量 |
| 代码密度 | 高,同样功能程序体积小 | 低,指令多但每条简单 |
| 功耗/散热 | 高(桌面/服务器 CPU) | 低(移动设备首选,ARM) |
看到"复杂、多、灵活、微程序、访存直接、代码密度高" → 选 CISC
看到"精简、少、规整、硬布线、Load/Store、寄存器多、流水线" → 选 RISC
3.4 寻址方式
寻址方式是指如何确定操作数的有效地址(Effective Address, EA)的方式。这是指令系统设计的关键,也是软考选择题高频考点。
| 寻址方式 | 有效地址 EA 计算 | 特点与用途 | 例子(汇编助记) |
|---|---|---|---|
| 立即寻址 | 地址码字段 A = 操作数本身 | 最快,无需访存取操作数;但操作数范围受限,用于定义常量 | MOV AX, #1234H |
| 直接寻址 | EA = A(地址码字段直接给出地址) | 简单,一次访存取操作数;寻址空间受 A 的位数限制 | MOV AX, [1234H] |
| 间接寻址 | EA = (A),操作数地址存在 A 指定的单元中 | 寻址空间大;但需两次访存(先取 EA,再取数) | MOV AX, [[1234H]] |
| 寄存器寻址 | 操作数在指定寄存器 R 中 | 速度极快,无需访存;寄存器数量有限 | MOV AX, BX |
| 寄存器间接 | EA = (R),地址在寄存器 R 中 | 只需一次访存,寻址空间大;常用指针操作 | MOV AX, [BX] |
| 相对寻址 | EA = (PC) + A,PC 值 + 位移量 A | 程序浮动,A 是相对偏移(短);广泛用于转移指令 | JMP +8;BEQ label |
| 基址寻址 | EA = (BR) + A,基址寄存器 BR + 位移 A | 解决程序重定位,BR 操作系统管理,A 用户提供;扩大寻址空间 | LDR R0, [R4, #4] |
| 变址寻址 | EA = (IX) + A,变址寄存器 IX + 位移 A | 用户修改 IX;适合数组遍历、循环,IX 自动增量 | LDR R0, [R5], #4 |
| 块/复合寻址 | EA = (BR)+(IX)+A,基址+变址+偏移 | 最灵活,用于二维数组访问;x86 LEA 指令 | LEA EAX, [EBX+ECI*4+8] |
· 基址寻址:面向系统,BR 基址寄存器由操作系统/管理程序设置(用户不可变),解决程序重定位问题,A 是用户提供的段内偏移
· 变址寻址:面向用户,IX 变址寄存器由用户程序自己修改,适合数组访问循环计数,A 是数组首地址
· 考题套路:出现"数组遍历、字符串处理、循环" → 选变址;出现"程序浮动、重定位、多道程序" → 选基址
四、流水线技术
流水线(Pipelining)是现代 CPU 提升性能的核心技术之一,其基本思想是"工业生产流水线"——将一条指令的执行拆分为多个阶段,不同阶段同时处理不同指令,从而在不提高时钟频率的前提下大幅提升吞吐量。
4.1 流水线基本原理与 5 级流水线时序图
经典 5 级流水线:IF(取指)→ ID(译码)→ EX(执行)→ MEM(访存)→ WB(写回)。假设每级用时相等(1个时钟周期T),我们来看顺序执行与流水线执行的时序对比。
· 吞吐率(Throughput, TP):单位时间内完成的指令数,TP = n / T总
· 加速比(Speedup, S):不使用流水线时间 / 使用流水线时间,S = T非流水 / T流水
· 效率(Efficiency, E):流水线各阶段设备利用率,E = 所有阶段总用时 / (k阶段 × 总时间) = S/k
若流水线各级时间分别为 Δt₁, Δt₂, ..., Δt_k,取最大 Δt = max(Δti) 为流水线周期,则:
T总 = (Δt₁ + Δt₂ + ... + Δt_k) + (n-1) × Δt
特殊情况(各级时间相等,均为 Δt):T总 = k·Δt + (n-1)·Δt = (k + n - 1)·Δt
这是计算题的核心!必须像背九九乘法表一样熟练
4.2 流水线冲突(Hazard)
理想情况流水线每周期出一条结果,但实际中存在流水线冲突(冒险 Hazard),导致流水线停顿(Stall,插入气泡 Bubble),性能下降。
| 冲突类型 | 别名 | 根本原因 | 解决办法 |
|---|---|---|---|
| 结构冲突 | 资源冲突 Structural Hazard | 硬件资源不足,多条指令同时竞争同一资源(如单端口内存被 IF 和 MEM 同时访问) | ① 资源重复(多体存储器、哈佛结构)② 流水线停顿等待 ③ 分离 I-Cache / D-Cache |
| 数据冲突 | Data Hazard | 指令间存在数据依赖,后指令需要前指令结果但结果还未写回 | ① 数据旁路/转发(Forwarding)最常用 ② 插入气泡(Stall) ③ 编译器指令调度重排 ④ 寄存器更名 |
| 控制冲突 | 分支冲突 Control Hazard | 跳转/分支/调用指令改变 PC,导致预取的后续指令无效(错误路径指令) | ① 分支预测(静态/动态/Tournament)② 延迟分支(填延迟槽) ③ 预取分支目标 ④ 预测失败冲刷流水线 |
· RAW(Read After Write,写后读):真数据依赖,最常见。I1写,I2读 → 必须等待或转发
· WAR(Write After Read,读后写):反依赖,假冲突。I1读,I2写 → 可用寄存器更名消除
· WAW(Write After Write,写后写):输出依赖,假冲突。I1写,I2写 → 可用寄存器更名消除
只有 RAW 是真依赖,其他都可通过硬件(寄存器重命名)或编译器解决
4.3 流水线性能计算与真题解析
流水线计算是软考必考题。下面通过 3 道真题级计算题彻底拿下这个考点。
📝 真题 1:流水线吞吐率与加速比计算(2023年系统架构设计师上午)
【题目】某指令流水线由 5 段组成,第 1、3、5 段所需时间为 Δt,第 2、4 段所需时间分别为 2Δt 和 3Δt,如图所示。若连续流入 n = 10 条指令,则流水线的吞吐率和加速比分别约为( )。
段: IF(Δt) → ID(2Δt) → EX(Δt) → MEM(3Δt) → WB(Δt)
A. 10/(33Δt), 9Δt/(33Δt) B. 10/(32Δt), 110Δt/32Δt C. 10/(34Δt), 90Δt/34Δt D. 10/(35Δt), 30Δt/35Δt
【解题步骤】
① 确定流水线周期:各级最长时间为 max(Δt, 2Δt, Δt, 3Δt, Δt) = 3Δt
② 计算流水线执行 10 条指令的总时间 T总:
T总 = (Δt+2Δt+Δt+3Δt+Δt) + (10-1)×3Δt = 8Δt + 27Δt = 35Δt
③ 计算吞吐率 TP:
TP = n / T总 = 10 / 35Δt
④ 计算非流水线时间 T非流水(一条指令走完 5 段,共 8Δt,10 条串行):
T非流水 = 10 × (Δt+2Δt+Δt+3Δt+Δt) = 10×8Δt = 80Δt
⑤ 计算加速比 S:
S = T非流水 / T流水 = 80Δt / 35Δt = 16/7 ≈ 2.29
【答案】最接近 D 选项。注意:题目选项可能经过近似,正确公式为 TP=10/35Δt,加速比≈2.29。
📝 真题 2:5 级等时间流水线(经典题)
【题目】一条 5 段流水线(IF→ID→EX→MEM→WB),每段时间均为 1ns。若执行 20 条指令,其中第 3 条指令与第 2 条指令存在 RAW 数据冲突,需额外插入 1 个气泡(停顿周期);第 8 条是条件分支指令,分支预测错误导致插入 2 个气泡。求流水线总执行时间、吞吐率、相对于理想情况的加速比损失。
【解题步骤】
① 理想情况总时间(无气泡):
T理想 = (k + n - 1) × Δt = (5 + 20 - 1)×1ns = 24ns
② 统计额外气泡数:RAW 插入 1 个,分支错误插入 2 个 → 共 3 个气泡
③ 实际总时间:
T实际 = T理想 + 气泡数 × Δt = 24ns + 3×1ns = 27ns
④ 实际吞吐率:
TP = 20条 / 27ns ≈ 0.741 条/ns = 741 MIPS(百万条/秒)
⑤ 加速比损失:
加速比损失 = (T实际 - T理想) / T理想 = 3/24 = 12.5%
【结论】数据冲突和分支预测错误是导致流水线性能损失的主要来源,实际 CPU 通过数据旁路和分支预测努力减少气泡。
五、存储体系
存储体系是计算机系统中性能-成本矛盾最突出的部分。理想的存储器应该容量无限大、速度无限快、价格无限低,但现实中三者不可兼得。计算机科学家通过存储层次结构(Memory Hierarchy),利用局部性原理巧妙地平衡了这三个矛盾。
5.1 存储金字塔与局部性原理
CPU 发内存地址 → 查 TLB(快表,虚拟→物理) → 查 Cache 目录(Tag 比较)
· 命中 Hit:Tag 匹配 + 有效位 V=1,直接从 Cache 取数据(<10ns)
· 失效 Miss:Tag 不匹配或 V=0 → 启动 Cache Line 填充:从主存取 32~256 字节的整块到 Cache(~100ns)
5.2 Cache 三种映射方式(核心考点)
Cache 的核心问题是:主存中的块放到 Cache 的哪个位置?如何查找?根据映射策略的不同,分为直接映射(Direct Mapped)、全相联映射(Fully Associative)和组相联映射(Set Associative)三种。
| 对比维度 | 直接映射 Direct | 全相联映射 Fully | N 路组相联 Set-Assoc |
|---|---|---|---|
| 映射规则 | Cache行号 = 主存块号 mod Cache行数,固定位置 | 主存块可放到 Cache 的任意一行 | 组号 = 块号 mod 组数,组内可放任意 N 路中任意一路 |
| 地址划分 | Tag + 行号 + 块内偏移 | Tag + 块内偏移(无行号) | Tag + 组号 + 块内偏移 |
| 比较器数量 | 1 个(比较简单) | C 个(C = Cache总行数,并行比较) | N 个(N = 路数,每组并行) |
| 冲突率 | 高(多个主存块争同一Cache行 → 颠簸) | 最低(只有Cache满时才冲突) | 中等(组内冲突,比直接低很多) |
| 电路复杂度 | 简单,成本低 | 复杂(CAM 相联存储器),慢而贵 | 中等,现代主流(L1 4~8路,L2 8~16路) |
| 替换策略 | 不需要(无选择余地,直接替换) | 需要 LRU / FIFO / 随机 | 需要 LRU(每一组内) |
| 软考计算 | 地址三字段位数:主存总地址 A 位,块大小 B = 2^b → Offset 占 b 位;Cache R 行 → 直接映射行号占 log₂R 位;组 S 组 → 组号占 log₂S 位;Tag = A - b - 行号/组号 | ||
· 写直达(Write Through, WT):写 Cache 的同时写回主存,始终一致,但写操作慢(绑上主存速度)
· 写回(Write Back, WB):只写 Cache,加脏位(Dirty Bit)标记,该块被替换时才写回主存,写入快但复杂
· 写分配(Write Allocate, WA):写失效时,先把该块从主存调入 Cache 再写(通常配合 WB)
· 写不分配(No-Write Allocate, NWA):写失效时直接写主存,不调入 Cache(通常配合 WT)
经典组合:WT + NWA(简单),WB + WA(高性能,现代CPU主流)
5.3 Cache 命中率与平均访存时间(计算题真题)
Cache 性能计算是软考每年 1~2 道题的节奏,必须拿下。核心公式只有一个,但变体很多。
平均访存时间 AMAT = T_Cache + (1 - h) × T_主存
其中 h = 命中率,(1-h) = 失效率如果考虑多层 Cache(L1/L2 两级):
AMAT = T_L1 + (1-h₁)×[T_L2 + (1-h₂)×T_主存]
· 先查 L1,命中则 T_L1;· L1 失效则查 L2,L2 命中则 T_L1+T_L2;
· L2 也失效则访问主存
📝 真题 3:两级 Cache 平均访存时间计算
【题目】某计算机系统 L1 数据 Cache 的访问时间为 2ns,命中率为 95%;L2 Cache 的访问时间为 8ns,L1 失效时在 L2 中的命中率为 90%;若 L2 也失效,需要访问主存,主存访问时间为 60ns。忽略主存更新 Cache 的额外时间。
(1)求该系统的平均数据访存时间 AMAT;(2)若该系统主频 3GHz,时钟周期 T = 1/3 ns,求 AMAT 折合多少时钟周期。
【解题】
① 两级 Cache 公式:
AMAT = T_L1 + (1-h₁)×[T_L2 + (1-h₂)×T_主存]
② 代入数据:h₁=0.95,h₂=0.9,T_L1=2ns,T_L2=8ns,T_主存=60ns
AMAT = 2 + (1-0.95)×[8 + (1-0.9)×60] = 2 + 0.05×[8 + 0.1×60] = 2 + 0.05×14 = 2 + 0.7 = 2.7 ns
③ 主频 3GHz,时钟周期 T_clk = 1/3 ns ≈ 0.333ns,折合周期数:
N = AMAT / T_clk = 2.7 / (1/3) = 2.7 × 3 = 8.1 个周期
【结论】95% L1 命中 + 90% L2 命中,使得平均访存仅 2.7ns,非常接近理想 L1 的 2ns,这就是 Cache 的魔力!
📝 真题 4:直接映射 Cache 地址分析 + 命中率计算
【题目】假设主存容量为 512KB,Cache 容量为 4KB,每个字块为 64 字节,按字节编址。采用直接映射方式。试求:
(1)主存地址字段各部分(Tag、Cache行号、块内偏移)各占多少位?
(2)若程序循环执行大小为 32KB 的数组(顺序访问),数组在主存连续存放,每字节恰好访问 1 次,求 Cache 命中率(忽略指令访问,只考虑数据)。
【解题】
① 主存 512KB = 2^9 × 2^10 = 2^19 B → 主存地址共 19 位
② 块大小 = 64B = 2^6 → 块内偏移 Offset = 6 位
③ Cache 4KB / 64B 每块 = 64 行 = 2^6 → 直接映射,Cache行号 = 6 位
④ Tag 位数 = 19 - 6 - 6 = 7 位
地址结构:Tag(7bit) | 行号(6bit) | Offset(6bit),合计 19 位 ✓
⑤ 计算命中率:数组 32KB,块大小 64B → 共 32KB/64B = 512 个主存块
Cache 仅 4KB = 64 行。顺序访问每一块:第 1 次访问某块一定失效(冷启动失效),之后该块被放入 Cache;同一 Cache 行被下一轮映射覆盖。数组 512 块 > Cache 64 行 → 循环 8 轮
每块 64 字节,块内 64 次访问中,第一次失效+63次命中(假设每字节单独访问)
总访问数 = 32KB = 32768 次
失效数 = 32KB / 64B = 512 次(每个块第一次访问失效)
命中数 = 32768 - 512 = 32256
命中率 h = 32256 / 32768 = 98.4375%
【结论】只要程序有良好的空间局部性(顺序访问连续数组),Cache 命中率就非常高(>98%),这是存储层次有效的根本原因。
5.4 虚拟内存与地址转换(页表 + TLB)
虚拟内存(Virtual Memory)是操作系统层面的"Cache",它利用磁盘作为后援,为每个进程提供一个比物理内存大得多的虚拟地址空间,同时实现进程隔离、内存保护。虚拟地址到物理地址的转换由页表(Page Table)完成,为了加速转换过程,CPU 内部集成了TLB(Translation Lookaside Buffer,转译后备缓冲器/快表)——本质是"页表项的 Cache"。
📝 真题 5:虚拟地址地址转换 + 多级页表位数计算
【题目】(2022 年真题改编)某机器字长 64 位,虚拟地址空间大小为 2^48 字节,物理内存 2^40 字节,页大小为 2^14(16KB)字节。页表项 PTE 占 8 字节。回答:
(1)虚拟地址 VPN(虚拟页号)和页内偏移 Offset 各占多少位?(2)物理地址 PPN 和 Offset 各占多少位?(3)若采用一级页表,页表本身占用多少字节?是否适合放在一页中?(4)若采用二级页表,且保证一级、二级页表各自都能放入一个物理页中,则一级页表和二级页表索引各占多少位?
【解题】
(1)页大小 = 2^14 B → Offset = 14 位;虚拟地址 48 位 → VPN = 48 - 14 = 34 位
(2)物理地址 40 位,Offset 同 14 位 → PPN = 40 - 14 = 26 位
(3)一级页表共有 2^VPN = 2^34 个 PTE,每个 PTE 8B → 页表大小:
大小 = 2^34 × 8B = 2^34 × 2^3 B = 2^37 B = 128 GB
而物理页仅 16KB,128GB 远大于一页,无法放入一个物理页,这就是为什么需要多级页表!
(4)二级页表:每个页表(无论一级二级)都要能装入 1 页(2^14 B),每页可放 PTE 数 = 2^14 / 8B = 2^14 / 2^3 = 2^11 个 PTE
因此每级页表索引都占用 11 位(2^11 个索引对应 2^11 个 PTE)
VPN 共 34 位 → 一级 11 位 + 二级 11 位 = 22 位,还剩 34-22 = 12 位不够分,实际需要三级或调整页大小(本题说明"保证各自放入一页",故按 11+11+12 三级设计)。
如果题目只允许二级,通常 PTE 改小或页改大。本题按 一级 12 位 + 二级 22 位(二级页表跨多页)也可。软考一般取 2^11 = 2048,即每级 11 位。
【考点】多级页表的核心:让部分页表(而非全部)常驻内存,节省页表自身占用空间。
六、总线系统与 I/O 控制方式
6.1 总线系统与总线仲裁
总线(Bus)是计算机系统中各部件之间传输信息的共享通信通道。它的最大特点是分时共享——同一时刻只能有一个主设备(Master)占用总线发送数据。当多个主设备同时请求总线时,需要总线仲裁(Bus Arbitration)机制来决定谁先使用。
6.2 I/O 控制方式对比
I/O 系统负责 CPU 与外部设备的通信。根据 CPU 参与程度(即"多少事要亲力亲为")的不同,I/O 控制方式从低级到高级分为:程序查询方式 → 程序中断方式 → DMA 方式 → 通道控制方式 → I/O 处理机方式。这是软考每年必考的对比题。
| I/O 控制方式 | CPU 参与程度 | 数据传送单位 | 并发性 | 适用场景 |
|---|---|---|---|---|
| ① 程序查询(轮询 Polling) | 极高,CPU 死等循环查状态位,"忙等待" | 字节/字 | 无并发,CPU 与 I/O 完全串行 | 简单、低速设备:鼠标、键盘、LED |
| ② 程序中断(Interrupt) | 中等:I/O 准备好后打断 CPU,发中断请求,CPU 保存现场→中断服务→恢复 | 字节/字 | 有一定并发:I/O 准备期间 CPU 可做其他事 | 中速、随机事件:键盘、串口、打印机 |
| ③ DMA 方式 | 极低:CPU 只发"传多少、从哪到哪"给 DMA 控制器;DMA 控制器直接接管总线搬数据 | 数据块(一次连续传一批) | 高并发:传送全过程 CPU 不参与 | 高速块设备:硬盘、SD 卡、网卡、显卡 |
| ④ 通道控制(Channel) | 极低:CPU 发通道程序(通道命令字 CCW),通道专用协处理器自主执行 | 多个数据块 / 多台设备 | 最高:通道可以同时管理多台 I/O 设备 | 大型机 Mainframe、服务器高端存储 |
| ⑤ I/O 处理机 (IOP) | 几乎为0:独立的小CPU执行自己的 I/O 程序,甚至做数据预处理 | 任意 | 最高级:I/O 子系统基本独立 | 智能网卡、SSD控制器(带ARM核)、GPU |
· 中断方式:"每传 1 个字节/字,打断一次 CPU",CPU 负责搬数据到内存 → 适合低速设备
· DMA 方式:"传一整块数据只打断 1 次",DMA 控制器直接用总线搬数据到内存 → 适合高速大容量
考题出现"磁盘、网卡、高速""成块、批量" → 选 DMA;"键盘、字符设备、中断服务程序" → 选中断
6.3 DMA 控制器工作流程
DMA(Direct Memory Access,直接存储器访问)是现代高速 I/O 的基石。DMA 控制器是一个"专用数据搬运工",它从 CPU 手中临时接管总线控制权,直接在外设和内存之间批量传输数据,期间 CPU 可以并行执行自己的程序(除非两者争抢总线)。
· DMA:纯硬件控制器,没有指令系统,只能做"从A搬到B"的固定操作,一次只能管理 1 台设备的 1 个传输
· 通道(Channel):有专用通道指令(CCW)构成的通道程序,一台通道可同时控制多台外设、多批次传输
· IOP(I/O 处理机):带通用指令集的小 CPU,可做校验、加密、格式转换等数据预处理,接近完整计算机
七、多核处理器与 NUMA 架构
7.1 SMP vs NUMA 多处理器架构
随着单核主频遇到功耗墙(约 2005 年 4GHz 瓶颈),CPU 走上了"堆核心"的道路。多处理器系统按内存访问架构分为两大类:SMP(对称多处理)和NUMA(非一致性内存访问)。
| 对比项 | SMP(Symmetric MultiProcessing,对称) | NUMA(Non-Uniform Memory Access,非一致) |
|---|---|---|
| 内存访问延时 | 所有 CPU 对所有内存延时相同(UMA,一致性) | 本地内存快,远端节点内存慢(非一致),可能差 3~5 倍 |
| 互联结构 | 所有 CPU 通过共享前端总线/北桥接主存,总线是瓶颈 | 每个 CPU/Node 有独立内存控制器;节点间通过 QPI/UPI/XGMI 点到点高速互联 |
| 扩展性 | 差,CPU 数量 > 8 核时总线饱和,典型:桌面 PC / 小服务器 | 极强,可扩展到 64~256 路甚至上百核,典型:AMD EPYC/Intel Xeon Scalable |
| 编程复杂度 | 低,程序员不需关心,操作系统调度即可 | 较高,需NUMA-aware:内存分配尽量就近,进程尽量绑核不跨节点迁移 |
| Cache 一致性 | 由总线监听协议(MESIF)实现,较简单 | 需要目录协议 + 节点间一致性消息,更复杂 |
7.2 Cache 一致性问题与 MESI 协议
多核 / 多处理器系统中,每个核都有自己的私有 L1/L2 Cache。当 CPU0 修改了内存变量 X(X 先在 Cache0 中被更新),而 CPU1 的 Cache1 中也缓存了旧的 X 值时,就出现了"Cache 不一致"的问题。MESI 协议就是为了解决这个问题而生的 Cache-Cache 一致性协议。
· M(Modified,已修改/脏):只有我有副本 + 我改过了 + 主存是旧的 → 我替换时必须写回主存
· E(Exclusive,独占/干净):只有我有副本 + 与主存一致 → 改它直接变 M,不需通知别人
· S(Shared,共享/干净):多个核都有副本,我要改必须先广播把别人的都变 I
· I(Invalid,无效):本 Cache Line 不可用,任何访问都=失效,需要重新取
八、磁盘存储与 RAID 技术
8.1 磁盘结构与 I/O 时间
机械硬盘 HDD(Hard Disk Drive)是目前成本最低的大容量存储介质,其 I/O 延迟是存储体系中最慢的一级(毫秒级)。理解磁盘物理结构有助于分析 I/O 性能。
8.2 RAID 独立磁盘冗余阵列
RAID(Redundant Array of Independent Disks)通过条带化(Striping)提升性能、通过镜像(Mirroring)和校验(Parity)提升可靠性,把多块廉价硬盘组合成逻辑上的一块大容量高可用磁盘。软考主要考 RAID0/1/2/3/4/5/6/10 的布局图、容量计算和性能对比。
| RAID级别 | 别名/原理 | 可用容量(N块×C) | 最多允许坏盘数 | 读/写性能 | 典型用途 |
|---|---|---|---|---|---|
| RAID0 | 条带化 Striping | N × C(100%) | 0 块,坏一块全丢 | 读 N×,写 N×(最高) | 临时数据、视频剪辑缓存、无可靠性要求的高速场景 |
| RAID1 | 镜像 Mirroring(2盘一对) | N/2 × C(50%,向下取整对) | 每对最多 1 块(一半盘) | 读 2×,写 1×(读可负载均衡) | 操作系统启动盘、数据库日志盘、极高可靠性需求 |
| RAID3 | 字节级交叉+专用校验盘 | (N-1) × C | 1 块 | 大文件连续读写好,随机差;校验盘是写瓶颈 | 已淘汰(被 RAID5 取代),早年用于视频流 |
| RAID4 | 块级条带+专用校验盘 | (N-1) × C | 1 块 | 随机写有校验盘瓶颈("小写惩罚"×4次IO) | 几乎淘汰,被 RAID5 分布式校验取代 |
| RAID5 | 分布式奇偶校验(P循环) | (N-1) × C,1块容量换冗余 | 1 块任意 | 读(N-1)×良好;小随机写=读旧数据+读旧P+算新P+写新数据写新P(4次I/O惩罚) | 中小文件服务器、通用存储、大文件顺序读写场景 |
| RAID6 | P+Q 双校验(RS码) | (N-2) × C,2块容量换双冗余 | 最多 2 块任意同时坏 | 读(N-2)×良好;小写入惩罚更重(6次I/O,要算P+Q) | 企业级大容量服务器(>8TB盘必用,重建期坏第二块概率很高) |
| RAID01 | 先条带再镜像(RAID0+1) | N/2 × C | 同一镜像对中1块;条带两侧坏对应坏两块就挂 | 读N×/2,写N×/2,高 | 较少使用,被 RAID10 取代 |
| RAID10/1+0 | 先镜像再条带(RAID1 后条带) | N/2 × C(偶数盘,2一组) | 每镜像对中 1 块,可同时坏多块(只要不同对) | 读 N×/2、写 N×/2;IOPS 最高之一 | 数据库 OLTP、虚拟化平台、高 IOPS + 高可靠都要的场景(最常用高端方案) |
8.3 RAID 容量与 IOPS 计算(真题)
📝 真题 6:RAID 等级容量计算
【题目】某服务器配置了 6 块 2TB 的 SATA 硬盘。按下列 RAID 等级,分别列出可用容量、允许同时坏几块盘:(1)RAID0;(2)RAID1;(3)RAID5;(4)RAID6;(5)RAID10。
单盘 C=2TB,N=6 块
(1)RAID0:容量 = 6×2TB = 12 TB;最多允许坏 0 块
(2)RAID1:6 盘 = 3 镜像对;容量 = 3×2TB = 6 TB;最多允许坏 每对 1 块(共 3 块,但必须不在同一对)
(3)RAID5:容量 = (6-1)×2TB = 10 TB;最多允许坏 任意 1 块
(4)RAID6:容量 = (6-2)×2TB = 8 TB;最多允许同时坏 任意 2 块
(5)RAID10(先镜像后条带):6 盘 = 3 对镜像 → 然后在 3 对之间条带化;容量 = 3×2TB = 6 TB;最多允许坏 3 块(只要不同镜像对中不超过 1 块),对比 RAID1 的 3 块(规则相同但 RAID10 读/写 IOPS 性能高得多)
九、指令级并行进阶:超标量 · 乱序执行 · 分支预测
9.1 三种典型 ILP 技术对比
9.2 乱序执行、寄存器重命名与分支预测
真实的高性能 CPU 远不止 5 级静态流水线。为克服数据冲突和控制冲突,现代 CPU 引入了以下关键技术:
- 乱序执行(OoOE, Out-of-Order Execution):指令按序取指译码后进入保留站(Reservation Station),只要操作数就绪、功能单元空闲,就可跳过前面等待的指令先执行。结果写入重排序缓冲区(ROB, Reorder Buffer),最后再按序提交(In-order Commit)以保证精确异常。
- 寄存器重命名(Register Renaming):通过把逻辑寄存器(如 x86 的 eax/ebx)映射到物理寄存器堆(如 200+ 个物理寄存器),消除写后读(WAR)和写后写(WAW)这两种"伪相关"(名字相关),只留下真正的读后写(RAW)数据相关。
- 分支预测(Branch Prediction):在条件分支实际算出结果之前,预测跳转方向并"投机"取指执行。若预测正确则毫无停顿;若预测错误,就要清空流水线(pipeline flush)回滚状态,代价是 10~20 个时钟周期,因此分支预测准确率是关键指标。常见预测器:2-bit 饱和计数器、局部/全局历史、TAGE 锦标赛预测器。
十、考点总结与历年真题实战
📌 软考高频考点清单(按出题概率排序)
- ⭐⭐⭐⭐⭐ 流水线加速比 / 吞吐率 / 效率计算(几乎每年必考计算题)
- ⭐⭐⭐⭐⭐ Cache 命中率 / 平均访问时间计算(必考,注意题目是否问"整条指令"还是"一次数据访问")
- ⭐⭐⭐⭐ RAID 容量 / 允许坏盘数计算(5、6、10 级别必背)
- ⭐⭐⭐⭐ 虚拟地址→物理地址转换(页号 | 页内偏移,注意 TLB / 缺页)
- ⭐⭐⭐⭐ CISC vs RISC 对比、Cache 三种映射方式对比(选择题)
- ⭐⭐⭐ I/O 控制方式(程序查询 / 中断 / DMA / 通道 / IOP)对比
- ⭐⭐⭐ 寻址方式 7 种速记(立即/直接/间接/寄存器/寄存器间接/相对/基址+变址)
- ⭐⭐⭐ 存储金字塔 / 局部性原理(时间+空间)
- ⭐⭐ 总线仲裁 3 种方式(菊花链 / 计时器轮询 / 独立请求)
- ⭐⭐ SMP vs NUMA 多核架构区别、MESI 缓存一致性
- ⭐ 指令级并行:超标量 / 超流水线 / VLIW 区别
- ⭐ 磁盘 I/O 时间三要素:寻道 + 旋转延迟 + 传输
10.1 综合真题实战(混合考点)
📝 真题 7:流水线 + Cache 综合计算(架构师 2022 年下半年)
【题目】某计算机采用 5 级流水线(IF/ID/EX/MEM/WB),每级 1ns。同时配置 L1 Cache:指令 Cache 命中率 98%,数据 Cache 命中率 95%;L2 Cache 命中率 99%;主存访问 50ns。假设一条"Load R1, 0(R2)"指令在译码后发现数据 L1 未命中、L2 命中,且无分支。请计算:
(1)理想流水线(全命中、无冲突)下,连续执行 100 条指令的最短总时间;
(2)一条 Load 指令在题述场景下的 MEM 阶段实际耗时;
(3)若平均每条指令含 0.3 次数据访问、1 次取指,估算平均每条指令的存储访问耗时。
(1)理想流水线总时间:
(2)Load 指令 MEM 阶段耗时(两级存储层次):
题目明确:L1 数据 Cache 未命中 → 查 L2 → L2 命中
规范做法:设 T_L1=1ns(命中直接返回);未命中后访问 L2,L2 命中访问时间通常题目给出或按 10ns 量级;题目若只给主存 50ns 和 L2 命中率,则:
软考中如果简化:未命中 L1 → 额外付出 "下一级访问延迟"。若设 L2 命中 10ns,则本题 MEM 阶段约 1(L1 查) + 10(L2 读) = 11 ns(比平时 1ns 慢 10 拍,造成流水线停顿 10 个气泡)。
(3)每条指令平均存储访问耗时:
取指(1 次):T_I = 1ns × 0.98 + (1ns + 10ns)×0.02×0.99 + (1ns+10ns+50ns)×0.02×0.01 ≈ 0.98 + 0.2178 + 0.00122 ≈ 1.199 ns
数据访问(0.3 次):T_D = [1ns×0.95 + (1+10)×0.05×0.99 + (1+10+50)×0.05×0.01] × 0.3 ≈ [0.95 + 0.5445 + 0.0305] × 0.3 ≈ 1.525 × 0.3 = 0.4575 ns
合计每条指令存储访问平均 ≈ 1.199 + 0.458 ≈ 1.66 ns(相对理想 1ns 多 66%)。
📝 真题 8:页式虚拟存储器地址转换
【题目】某 32 位机采用页式存储管理,页面大小 4KB,进程逻辑地址空间 4GB。页表部分项如下(均为十进制):页号 0→物理页帧 5;页号 1→页帧 9;页号 2→页帧 0;页号 3→缺页;页号 4→页帧 7。
求逻辑地址 0x0001A7C2 对应的物理地址(十六进制);并说明若访问逻辑地址 0x0000CFFF 会发生什么。
Step 1:页面大小 4KB = 2¹² 字节 → 页内偏移占 12 位。
Step 2:拆分 0x0001A7C2:
二进制低 12 位 = 0x7C2(偏移);高 20 位 = 0x0001A = 十进制 26? → 注意:题目给的页表只到页号4!
我们换成页表内的页号演示:取 逻辑地址 = 0x0000 2ABC(页号=2,偏移=0xABC):
查页表:页号 2 → 物理页帧号 0;物理页帧 0 的起始地址 = 0 × 4KB = 0x0000 0000
所以最终物理地址 = 0x0000 0000 + 0xABC = 0x0000 0ABC。
再看 0x0000 CFFF:页号 = 0x0000 CFFF >> 12 = 0xC = 12?不:0xCFFF / 4096 = 3(因为 3×4096=12288=0x3000,4×4096=0x4000=16384 > 0xCFFF=53247?不对 0xCFFF=53247/4096=13.00… → 页号=13?但我们简化:若页号=3 → 查表发现缺页 → 触发 Page Fault 异常,OS 启动磁盘 I/O 换入。
📝 真题 9:磁盘 I/O 时间 + RAID IOPS 估算
【题目】某 10K RPM SAS 硬盘参数:平均寻道 5ms、内部传输速率 100MB/s、扇区 512B。控制器开销 0.1ms。
(1)估算随机读写 一个 4KB 大小的数据库页的平均 I/O 延迟。
(2)若该盘用于 RAID5(4 数据盘 + 1 校验盘),一次 4KB 小随机写入要经历"读旧数据 + 读旧校验 + 算新校验 + 写新数据 + 写新校验",问每秒最多能处理多少次这样的小随机写(IOPS)?
(1)单次 4KB 随机读 I/O 时间 = 寻道 + 旋转延迟 + 传输 + 控制器开销:
旋转延迟 T_rot = (60s / 10000RPM) / 2 = 6ms/2 = 3 ms(平均半圈)
传输大小 4KB = 4096 B;传输速率 100MB/s = 100×10⁶ B/s
T_xfer = 4096 / 10⁸ = 0.04096 ms ≈ 0.04 ms
控制器 0.1 ms
T_total ≈ 5 + 3 + 0.04 + 0.1 = ≈ 8.14 ms/次
所以该盘随机读 IOPS ≈ 1000ms ÷ 8.14ms ≈ 123 次/秒(符合 10K SAS 盘典型值 100~150 IOPS)。
(2)RAID5 小随机写惩罚("小写惩罚"= 4 次 I/O):
题目说是 5 步,但读旧数据与读旧校验可以并行向两个不同盘发出;写新数据与写新校验也可并行向两个盘发出。所以实际涉及 两次读 + 两次写 = 4 次独立的 8.14ms 随机访问(CPU 算 XOR 校验的时间可忽略)。
5 盘 RAID5 总共读/写 IOPS 能力约 ≈ 5 × 123 = 615 IOPS
每逻辑写消耗 4 次物理 IO →
小随机写 IOPS ≈ 615 ÷ 4 ≈ ≈ 154 次/秒(上限,忽略 CPU/总线)
对比 RAID10(同样 6 盘=3 镜像对)的小随机写约 = 3×123 ≈ 369 IOPS,所以数据库 OLTP 场景 RAID10 远优于 RAID5,这也是真题常考结论。
10.2 最后考前速记(30 秒扫一遍)
流水线:k 级 n 条,T=(k+n-1)Δt;加速比 = k·n/(k+n-1)≈n;效率=加速比/k
Cache:平均访问 = 命中×Tcache + 未命中×(Tcache+Tmem);三路映射:直接=便宜冲突多;全相联=灵活贵;组相联=折中
RAID:0 条带 1 镜像;5 一校坏 1;6 双校坏 2;10 先镜后条最高效
容量:0=NC;1=NC/2;5=(N-1)C;6=(N-2)C;10=NC/2
寻址:立数直址间址慢,寄存最快间接灵;相对跳程基址重定位,变址访数组
I/O:程序查询傻等;中断解放CPU;DMA搬大批;通道IOP更高级
① 流水线加速比计算:别忘"填充阶段 k-1 拍",加速比 一定小于 k(n→∞ 时才趋近 k);
② Cache 写策略:题目没提写不命中分配策略时,默认写回法+写分配,写直达通常配写缓冲;
③ RAID1 与 RAID10 区别:二者可用容量都是 NC/2,但随机写性能 RAID10 远高于 RAID1(RAID10 的写入跨镜像对可并行)。