《结构化计算机组织》第6版
Andrew S. Tanenbaum & Todd Austin 著,Pearson 2013 年出版。 计算机组成原理领域的经典教材,以分层抽象的视角贯穿全书,从数字逻辑层一直到汇编语言层,揭示计算机系统的本质结构。
核心观点
1. 计算机是一个多层抽象系统
全书最核心的思想:计算机不是单一的硬件实体,而是由多个抽象层次(levels)堆叠而成的系统。每一层都有自己的指令集架构和数据类型,对下一层进行封装和抽象。
六层模型(从下到上):
| 层级 | 名称 | 描述 |
|---|---|---|
| Level 0 | 数字逻辑层(Digital Logic Level) | 门电路、触发器、寄存器,最底层的硬件实现 |
| Level 1 | 微体系结构层(Microarchitecture Level) | 微指令控制的数据通路,实现 ISA 层指令 |
| Level 2 | 指令集架构层(ISA Level) | 机器指令集,程序员看到的硬件接口 |
| Level 3 | 操作系统层(Operating System Level) | 虚拟内存、进程管理、系统调用 |
| Level 4 | 汇编语言层(Assembly Language Level) | 汇编指令、宏、链接加载 |
| Level 5 | 高级语言层(不在本书重点) | C/Java 等高级语言 |
关键洞见:每一层都可以独立设计和改进,只要保持接口稳定。这就是为什么 x86 指令集 40 年没变,但底层微架构已经进化了十几代。
2. 三种典型架构贯穿全书
全书用三款真实芯片作为贯穿案例,从第1章到第8章反复对比,体现不同设计权衡:
| 架构 | 代表芯片 | 定位 | 特点 |
|---|---|---|---|
| x86 / CISC | Intel Core i7 | 高性能桌面/服务器 | 复杂指令集,向后兼容负担重,微架构极其复杂 |
| ARM / RISC | TI OMAP4430 (ARM Cortex-A9) | 移动/嵌入式 | 精简指令集,低功耗,片上系统(SoC) |
| AVR / RISC | Atmel ATmega168 | 8位微控制器 | 极简设计,资源极度受限,Arduino 核心 |
这种”一以贯之”的对比式讲解是本书最大特色——不是孤立地讲概念,而是在三种完全不同的芯片上看同一个概念如何落地。
各章核心要点
第1章:引言(Introduction)
分层结构的起源:从编程语言的角度看,每一层都是一台虚拟机。早期计算机只有两层(ISA + 微架构),现在已经六层甚至更多。
计算机五代发展史:
- 第0代(1642–1945):机械计算机。Pascal 加法器、Babbage 分析机(通用可编程,Ada Lovelace 是第一位程序员)、Zuse 的继电器计算机
- 第1代(1945–1955):真空管。Colossus(英国密码破译,第一台电子数字计算机)、ENIAC(18000 个真空管,30 吨重)、EDSAC(剑桥,1949)
- 第2代(1955–1965):晶体管。IBM 7094、DEC PDP-1,小型机诞生
- 第3代(1965–1980):集成电路。IBM System/360(系列兼容机概念)、DEC PDP-11、摩尔定律开始生效
- 第4代(1980–?):超大规模集成(VLSI)。微处理器、PC、互联网
- 第5代:低功耗与不可见计算。物联网、嵌入式、可穿戴
计算机谱系:从一次性计算机 → 微控制器 → 移动/游戏设备 → PC → 服务器 → 大型机,本质都是同样的原理,只是规模和权衡不同。
第2章:计算机系统组成(Computer Systems Organization)
处理器(CPU):
- CPU 组成:数据通路 + 控制单元
- 指令执行周期:取指 → 译码 → 执行 → 写回
- RISC vs CISC:RISC 指令少而简单,CISC 指令多而复杂;现代 CISC(如 x86)内部已经是 RISC 内核(微操作)
- 指令级并行(ILP):流水线、超标量、乱序执行
- 处理器级并行:多核、多线程
主存(Primary Memory):
- 位、地址、字节序(大端 vs 小端)
- 纠错码(ECC):汉明码
- 缓存(Cache):时间局部性 + 空间局部性
- 内存类型:DRAM、SRAM、ROM
辅存(Secondary Memory):
- 内存层次结构:寄存器 → L1 → L2 → L3 → 主存 → 磁盘 → 备份
- 磁盘:磁道、扇区、柱面,寻道时间 + 旋转延迟 + 传输时间
- RAID:0/1/2/3/4/5/6 各级别原理与权衡
- SSD:闪存,无机械延迟,但有擦写次数限制
- 光盘:CD-ROM、DVD、Blu-ray
I/O 系统:
- 总线:数据总线、地址总线、控制总线
- 各种 I/O 设备:终端、鼠标、触摸屏、打印机、通信设备、数码相机
- 字符编码:ASCII、Unicode、UTF-8
第3章:数字逻辑层(The Digital Logic Level)
门电路与布尔代数:
- 基本门:AND、OR、NOT、NAND、NOR、XOR
- 布尔代数定律:交换律、结合律、分配律、德摩根定律
- 卡诺图化简
- NAND 门的通用性:只用 NAND 可以实现任何逻辑函数
基本数字电路:
- 集成电路(IC):SSI/MSI/LSI/VLSI/ULSI
- 组合电路:多路选择器、译码器、编码器、比较器
- 算术电路:半加器、全加器、进位链、加法器、ALU
- 时钟:同步电路的节拍器
存储器电路:
- 锁存器(Latch):SR 锁存器,最简单的存储单元
- 触发器(Flip-Flop):D 触发器,边沿触发
- 寄存器:由触发器组成
- 内存芯片组织:行地址 + 列地址 → 二维阵列
- RAM vs ROM:静态 RAM(快、贵)、动态 RAM(慢、便宜)、PROM、EPROM、EEPROM、Flash
CPU 芯片与总线:
- 总线仲裁:菊花链、集中式、分布式
- 总线操作:读操作、写操作的时序
- 案例:PCI 总线、PCI Express(串行点对点)、USB(通用串行总线)
接口:I/O 接口电路、地址译码
第4章:微体系结构层(The Microarchitecture Level)
这是全书最核心、最有深度的一章,揭示了指令集是怎么”造”出来的。
Mic-1 微架构:
- 数据通路(Data Path):寄存器、ALU、移位器、总线
- 微指令(Microinstruction):每一条微指令控制数据通路的一组信号
- 微程序控制:用”软件”(微程序)来实现硬件指令集
IJVM 指令集:
- 基于栈的虚拟机(类似 JVM 的子集)
- 栈式架构:操作数都在栈上,指令隐式操作栈顶
- 指令:ILOAD、ISTORE、IADD、ISUB、IMUL、IFEQ、GOTO 等
微架构设计演进(性能优化的四代设计):
| 设计 | 名称 | 关键优化 | 速度提升 |
|---|---|---|---|
| Mic-1 | 基础设计 | 每条微指令一个周期 | 1x(基准) |
| Mic-2 | 预取 | 预取队列,取指与执行重叠 | ~2x |
| Mic-3 | 流水线 | 三级流水线 | ~3x |
| Mic-4 | 七段流水线 | 深度流水 + 译码队列 | 更高 |
性能优化技术:
- 缓存:减少访存延迟
- 分支预测:静态预测 vs 动态预测,分支历史表(BHT),目标缓冲(BTB)
- 乱序执行 + 寄存器重命名:Tomasulo 算法思想,消除假依赖
- 推测执行:预测分支后继续执行,错了就回滚
真实案例对比:
- Core i7:极其复杂的乱序超标量微架构,4 发射 + 大量重排序缓冲
- OMAP4430 ARM Cortex-A9:双发射乱序,比 i7 简单得多
- ATmega168:根本没有微架构层,ISA 直接就是硬件实现
第5章:指令集架构层(The Instruction Set Architecture Level)
ISA 是软件与硬件之间最重要的接口——硬件设计者实现它,编译器开发者使用它。
ISA 核心属性:
- 内存模型:字节序、对齐、地址空间
- 寄存器:通用寄存器、特殊寄存器、状态寄存器
- 指令类型:数据传送、算术逻辑、控制转移、I/O
数据类型:
- 数值型:整数(有符号/无符号)、浮点数、BCD
- 非数值型:字符、字符串、布尔
指令格式设计:
- 设计准则:短指令、操作码扩展、寻址字段
- 扩展操作码(Expanding Opcodes):常用指令短编码,不常用指令长编码,压缩平均码长
- 三种架构对比:x86 变长指令(1-15 字节)、ARM 定长 32 位、AVR 16/32 位混合
寻址方式(10种):
- 立即寻址 — 操作数在指令中
- 直接寻址 — 地址在指令中
- 寄存器寻址 — 操作数在寄存器中
- 寄存器间接寻址 — 地址在寄存器中
- 变址寻址 — 基址+偏移
- 基址-变址寻址 — 两个寄存器相加
- 栈寻址 — 操作数在栈顶
- 相对寻址 — PC + 偏移
- 页寻址 — 页号 + 页内偏移
- 段寻址 — 段寄存器 + 偏移
正交性原则:操作码与寻址方式应该相互独立,每种操作可以使用任何寻址方式。x86 的 CISC 设计正交性较差,ARM 的 RISC 设计正交性较好。
指令类型:
- 数据传送指令(MOV、LOAD、STORE、PUSH、POP)
- 算术逻辑指令(ADD、SUB、MUL、DIV、AND、OR、NOT、移位)
- 比较和条件转移(CMP、JZ、JNZ、JC、JMP)
- 过程调用与返回(CALL、RET)
- 循环控制(LOOP)
- I/O 指令(IN、OUT,或内存映射 I/O)
流程控制与可重入代码:
- 子程序调用的三种实现:程序控制方式、协同例程、陷阱
- 可重入代码:可以被中断并安全重入的代码
- 折半查找、快速排序等算法的递归实现
IA-64 / Itanium 2:
- EPIC(显式并行指令计算)理念:把并行性检测交给编译器
- 谓词执行(Predication):用谓词消除分支
- 推测加载(Speculative Loads):提前加载,错了就忽略
- 历史教训:Itanium 在商业上失败了,因为编译器很难充分利用 ILP,而 x86 的动态超标量反而更有效
第6章:操作系统层(The Operating System Level)
虚拟内存:
- 分页(Paging):虚拟地址 → 物理地址的映射,页表、TLB
- 页替换算法:FIFO、时钟算法、LRU、工作集模型
- 页面大小与碎片
- 分段(Segmentation):逻辑段,如代码段、数据段、栈段
- Core i7 的虚拟内存:四级页表 + 段机制
- ARM 的虚拟内存:TLB + 页表,更简洁
硬件虚拟化:
- Core i7 的 VT-x 技术:支持虚拟机监控器(VMM)
- 陷入与模拟(Trap-and-emulate)
操作系统级 I/O:
- 文件抽象:打开、读、写、关闭
- 目录管理
并行处理:
- 进程创建
- 竞态条件(Race Condition):多个进程共享数据的经典问题
- 信号量(Semaphore):Dijkstra 发明,P/V 操作,解决同步与互斥
第7章:汇编语言层(The Assembly Language Level)
汇编语言基础:
- 为什么用汇编:极致性能、嵌入式、系统编程
- 语句格式:标号 + 操作码 + 操作数 + 注释
- 伪指令(Pseudoinstruction):不是机器指令,是给汇编器的指令
宏(Macros):
- 宏定义、调用、展开
- 带参数的宏
- 高级特性:条件汇编、嵌套宏
- 宏的实现:符号表 + 文本替换
汇编过程:
- 两遍汇编器(Two-Pass Assembler):
- 第一遍:构建符号表,确定所有标号的地址
- 第二遍:生成机器码
- 符号表:哈希表实现,快速查找
链接与加载:
- 链接器任务:符号解析 + 重定位
- 目标模块结构:代码段、数据段、bss 段、符号表、重定位表
- 绑定时间:编译时、链接时、加载时、运行时
- 动态链接:共享库(.so / .dll),运行时加载,节省内存
第8章:并行计算机体系结构(Parallel Computer Architectures)
本书第 6 版新增的重要一章,反映多核时代的现实。
片上并行(On-Chip Parallelism):
- 指令级并行(ILP):超标量、超流水线、VLIW
- 片上多线程:细粒度多线程、粗粒度多线程、同时多线程(SMT,Intel 叫超线程)
- 单芯片多核处理器:CMP,每个核是独立的 CPU
协处理器(Coprocessors):
- 网络处理器:专门处理网络数据包
- GPU:图形处理器,高度并行的流式架构,GPGPU 通用计算
- 密码处理器:专门加解密
共享内存多处理器(Shared-Memory Multiprocessors):
- 多处理器 vs 多计算机:共享内存 vs 消息传递
- 内存一致性模型:顺序一致性、弱一致性、释放一致性
- UMA:均匀内存访问,所有 CPU 访问所有内存延迟相同(SMP)
- NUMA:非均匀内存访问,本地内存快、远程内存慢
- COMA:缓存一致性 NUMA,内存本身就是缓存
- 缓存一致性协议:MESI 协议(Modified/Exclusive/Shared/Invalid),监听协议 vs 目录协议
消息传递多计算机(Message-Passing Multicomputers):
- 互连网络:拓扑结构(网格、环面、超立方体、树、胖树)、路由算法、流控
- MPP(大规模并行处理器):BlueGene 系列(3D torus 拓扑,73728 节点,集体网络 + 屏障网络)
- 集群计算:用商用 PC + 以太网/InfiniBand 组成的并行系统
- 调度、性能分析
网格计算(Grid Computing):跨地域的松散耦合计算资源池
三大核心主题与设计原则
1. 抽象与分层
复杂性管理的核心手段。每一层都隐藏下层的复杂性,只向上提供简洁的接口。
- 数字逻辑层隐藏晶体管的物理特性
- 微架构层隐藏电路实现细节,提供 ISA
- ISA 层隐藏微架构差异,提供编程模型
- OS 层隐藏硬件细节,提供系统调用
- 汇编层隐藏机器码细节,提供符号化编程
2. 性能优化的各种手段
| 优化层级 | 技术 | 原理 |
|---|---|---|
| 逻辑层 | 流水线 | 把任务拆成多段,重叠执行 |
| 微架构 | 超标量/乱序 | 同一时刻执行多条指令 |
| 内存系统 | 缓存层次 | 利用局部性,用高速缓存弥补访存墙 |
| 处理器 | 多核 | 复制核心,横向扩展 |
| 系统级 | 并行计算 | 多机协同解决更大问题 |
3. 设计权衡(Trade-offs)
- 性能 vs 功耗:手机用 ARM(低功耗),服务器用 x86(高性能)
- 简单 vs 强大:RISC 简单易流水,CISC 强大但复杂
- 硬件 vs 软件:功能放硬件更快,放软件更灵活
- 面积 vs 速度:缓存越大命中率越高,但延迟也越高
- 成本 vs 可靠性:ECC 内存更可靠但更贵,RAID 同理
关键概念索引
- 虚拟机(Virtual Machine):每一层都是下一层之上的虚拟机
- 数据通路(Data Path):CPU 中执行运算的硬件部分
- 微指令(Microinstruction):控制数据通路信号的低级指令
- 微程序(Microprogram):实现 ISA 的微指令序列
- 指令级并行(ILP):同时执行多条指令的能力
- 内存墙(Memory Wall):CPU 速度增长远快于内存,访存成为瓶颈
- 缓存一致性(Cache Coherence):多核下各缓存保持一致的协议
- MESI 协议:最常用的缓存一致性协议
- 分支预测(Branch Prediction):预测分支方向,保持流水线满载
- 寄存器重命名(Register Renaming):消除写后写、写后读假依赖
- 虚拟内存(Virtual Memory):给每个进程独立的地址空间
- TLB:Translation Lookaside Buffer,地址翻译缓存
- UMA / NUMA / COMA:三种共享内存多处理器架构
- MPP / Cluster / Grid:三种并行计算机规模
与其他知识的关联
- 《程序员的自我修养》-链接、装载与库 — 第7章链接与加载部分的深入展开,本书讲原理,那本书讲 Linux 实际实现
- 《SICP》-计算机程序的构造和解释-第二版 — 同样是分层抽象思想,但 SICP 讲的是软件层(解释器/求值器),本书讲的是硬件层
- 《代码整洁之道》-Clean Code-Robert-C-Martin — 写代码层面的整洁,本书揭示代码下面的硬件本质
- 《程序设计实践》-The-Practice-of-Programming-Kernighan-Pike — 编程实践层面,与本书的硬件层面知识互补
- 《奇思妙想》-15位计算机天才及其重大发现 — 第1章计算机发展史中提到的很多人物在那本书中有更详细的访谈
学习建议
- 重点读第4章(微体系结构):这是全书最精华的部分,理解了 Mic-1 到 Mic-4 的演进,就理解了现代 CPU 为什么是这样
- 三种架构对比学习:每学一个新的概念(缓存、流水线、虚拟内存),分别想 x86/ARM/AVR 上是怎么实现的
- 动手实验:可以用 Logisim 搭建简单 CPU,或者学 ARM 汇编在树莓派上实验
- 第8章是趋势:并行计算是当前和未来的主题,值得反复研读
Tanenbaum 的书有个共同特点:用简单的例子讲清楚复杂的概念。从 Mic-1 这个极简微架构开始,一步步加优化,最后你会发现现代 CPU 的那些花哨技术(乱序执行、分支预测、寄存器重命名)本质上都是从简单模型演进而来的。