计算机科学

计算机系统:程序员的视角

Randal E. Bryant and David R. O'Hallaron

英文原名: Computer Systems: A Programmer's Perspective

计算机系统:程序员的视角 cover

以程序员为中心,贯通数据表示、机器代码、内存、进程、链接、网络与并发的计算机系统导论。

需要的基础

熟悉 C 或 C++ 编程;不要求事先了解计算机硬件或汇编语言。

版次
3
出版年份
2015
难度等级
中级
学术层次
本科
计算机系统C语言汇编语言内存层次操作系统网络并发

01 / 导读

导读

引用

Bryant, R. E., & O'Hallaron, D. R. (2015). Computer Systems: A Programmer's Perspective (3rd ed.). Pearson.

章节概要

全书分三部分,共十二章,另有一个关于错误处理的简短附录。作者明确说明了取舍标准:只有当某个主题会影响用户级 C 程序的性能、正确性或实用性时,才会收入书中。各章末尾有小结和参考文献说明,多数章还附有习题。正文中练习题的解答集中放在每章末尾。

第一部分:程序结构和执行(第 1–6 章)

第 1 章:A Tour of Computer Systems(计算机系统漫游)

本章沿着一个简单的“hello, world”程序的生命周期,引出以下主要主题:信息就是位加上上下文;编译系统对程序的翻译;运行程序的硬件组成;高速缓存与存储层次;操作系统的进程、线程、虚拟内存和文件;以及通过网络通信。章末给出三个反复出现的主题:Amdahl 定律、并发与并行,以及抽象。

第 2 章:Representing and Manipulating Information(信息的表示和处理)

本章涵盖以下内容:

  • 信息存储:十六进制、字长、字节顺序,以及 C 中的位级运算和逻辑运算。
  • 整数表示:无符号编码和补码编码、转换、符号扩展与截断。
  • 整数运算。
  • 浮点数:IEEE 表示、舍入,以及 C 中的浮点数。

作者强调这些内容对程序员的影响,例如两个正数相加可能得到负数。他们指出,读者最常觉得这一章吃力。第三版标出了讲法转向数学化的地方,方便读者第一遍先略读。

第 3 章:Machine-Level Representation of Programs(程序的机器级表示)

读者在这里学习阅读 C 编译器生成的 x86-64 代码,内容包括:数据传送和算术运算;条件码、跳转、循环与 switch 语句;过程与运行时栈;数组、结构与联合,以及对齐;指针;使用 gdb 调试器;缓冲区溢出及其防御;浮点代码。

第 4 章:Processor Architecture(处理器体系结构)

本章围绕 Y86-64 指令集设计一个简化的处理器。它先介绍逻辑设计和硬件控制语言 HCL,再分阶段构建顺序实现。随后解释流水线的原理与局限,并发展出一个五级流水线实现,涉及冒险、异常处理、控制逻辑和性能分析。

第 5 章:Optimizing Program Performance(优化程序性能)

本章先讲优化编译器能做什么、不能做什么,然后消除循环低效、冗余的过程调用和不必要的内存引用。在介绍现代乱序处理器的工作模型之后,本章讲解循环展开、多累加器和重新结合,寄存器溢出和分支预测错误等限制因素,内存性能,以及性能剖析。

第 6 章:The Memory Hierarchy(存储器层次结构)

本章涵盖存储技术(RAM、磁盘、固态硬盘)、局部性和存储器层次结构,以及高速缓存存储器,包括直接映射、组相联和全相联缓存、写操作,以及缓存参数对性能的影响。最后讲如何编写缓存友好的代码,并从“存储器山”的角度看性能。

第二部分:在系统上运行程序(第 7–9 章)

第 7 章:Linking(链接)

第 7 章涵盖:编译器驱动程序与静态链接;目标文件、符号与符号解析;重定位;可执行文件与加载;使用共享库的动态链接;位置无关代码;库打桩;以及操作目标文件的工具。

第 8 章:Exceptional Control Flow(异常控制流)

本章介绍异常、进程、进程控制、信号和非本地跳转。作者说,读完这一章,读者就能写出一个带作业控制的简单 Unix shell。

第 9 章:Virtual Memory(虚拟内存)

本章讲解物理寻址与虚拟寻址,并把虚拟内存作为缓存、内存管理和保护的工具来介绍。随后涵盖:地址翻译;Intel Core i7 与 Linux 内存系统的案例研究;内存映射;动态内存分配;垃圾收集;以及 C 程序中常见的与内存有关的错误。

第三部分:程序间的交互和通信(第 10–12 章)

第 10 章:System-Level I/O(系统级 I/O)

本章涵盖:Unix I/O 与文件;打开、读取和写入文件;处理“不足值”的健壮 I/O 包;文件元数据与目录;文件共享与 I/O 重定向;以及标准 I/O。本章为后两章做准备。

第 11 章:Network Programming(网络编程)

本章介绍客户端-服务器模型、网络与全球 IP 因特网、套接字接口、Web 服务器,以及一个 Tiny Web 服务器。作者称这一章是切入网络编程的一个薄片,目标是做出一个简单的 Web 服务器。

第 12 章:Concurrent Programming(并发编程)

最后一章比较三种并发方式:基于进程、基于 I/O 多路复用和基于线程。随后讲共享变量、用信号量同步,以及用线程实现并行。章末讨论其他问题:线程安全、可重入性、竞争和死锁。

附录 A:Error Handling(错误处理)

这是一个简短的附录,介绍 Unix 系统中的错误处理和错误处理包装函数。

核心概念

第一部分:程序结构和执行(第 1–6 章)

  • 补码和 IEEE 浮点表示:为什么有限的位模式会产生令人意外的算术结果。
  • 机器级代码与运行时栈:C 语言结构和过程如何对应到指令。
  • 流水线:让指令的各个阶段重叠执行,以及限制流水线的冒险。
  • 局部性与存储器层次结构:为什么决定性能的是访问模式,而不仅是处理器速度。

第二部分:在系统上运行程序(第 7–9 章)

  • 链接与重定位:目标文件和库如何变成可执行文件。
  • 异常控制流:异常、信号和进程是并发的来源。
  • 虚拟内存与动态分配:地址翻译,以及 malloc 和 free 的实现。

第三部分:程序间的交互和通信(第 10–12 章)

  • Unix I/O 与套接字:网络程序的基本构件。
  • 并发服务器:比较进程、I/O 多路复用和线程三种方式。
  • 同步:信号量、竞争和死锁。

评析

优点

  • 清晰的组织思想。 作者把“构建者视角”与程序员视角相对照,并对每个主题应用同一条取舍标准。因此,链接、信号和 malloc 被收入书中,而加法器或总线的详细设计被略去。
  • 主动学习融入书中。 新概念之后紧跟练习题,解答放在每章末尾。习题标有工作量等级,从几分钟到十小时的实验不等。所有代码示例都在 Linux 上编译运行过,源代码可从本书网站获得。
  • 来自长期开设课程的实验。 前言介绍了与本书配套的实验:数据实验、二进制炸弹、缓冲区溢出、体系结构、性能或缓存、shell、malloc 和代理实验。供自学使用、不含答案的版本可在作者网站上获得。
  • 对 C 语言新手的支持。 “New to C?”提示指出语言方面的要点,网络附注(web aside)则把补充材料移出正文。
  • 使用灵活。 前言把各章映射到五种课程类型,从计算机组成课程到系统编程课程都有对应安排。

局限

  • 绑定单一平台。 本书面向 x86-64 机器代码、gcc 编译器和 Linux。使用其他指令集的读者看到的机器代码会有所不同,不过作者称整体行为应当一致。
  • 需要 C 语言基础。 作者假定读者熟悉 C 或 C++。只会 Java 的读者需要多花力气,只会 Python、Ruby 或 Perl 的读者则被建议先学 C。
  • 简化的处理器。 第 4 章为讲解流水线设计了 Y86-64 处理器。它是 x86-64 的精简子集,属于教学用设计,而不是商用处理器的模型。
  • 有意为之的取舍。 作者把网络编程一章称为一个薄片,取舍标准也排除了加法器设计这类硬件主题。
  • 硬件示例较旧。 本版出自 2015 年,处理器和缓存示例反映的是当时的机器。
  • 习题随版本而异。 CMU 课程教学人员提醒,早期版本与第三版差异很大,汇编语言部分尤其明显。他们还指出,第三版的平装本/国际版配有不同的练习题和习题,并批评了其中一些题目;他们提到的 Kindle 版也使用这套题目。如果你打算跟着课程做习题,应留意手头的版本。

在课程中的定位

《Computer Systems: A Programmer's Perspective》从软件一侧审视机器。几本相关的书可以排在它之前、与它并行或排在它之后:

  • 之前: Petzold 的 Code 是面向普通读者的叙述性入门。Nisan 和 Schocken 的 The Elements of Computing Systems 以项目方式从逻辑门起步搭建一台计算机。两者都可以排在本书之前。
  • 并行: Harris 和 Harris 的 Digital Design and Computer Architecture, RISC-V Edition 从硬件向上讲,并让学生自己设计处理器,因此可以与本书第 4 章搭配。
  • 之后: Hennessy 和 Patterson 的 Computer Architecture: A Quantitative Approach 是研究生层次的体系结构定量研究。Shen 和 Lipasti 的 Modern Processor Design 详细讲述了第 5 章只用模型概略描述的乱序超标量处理器。

如何使用本书

本书面向能用 C 或 C++ 编程、想弄清自己的程序底层发生了什么的计算机和工程专业学生。不要求具备硬件或汇编语言经验。

依据前言中的课程类型,实用的安排如下:

  • 面向程序员的课程核心: 第 1 至 3 章和第 5 至 9 章,从数据表示一路讲到机器代码、优化、存储器层次结构、链接、进程和虚拟内存。
  • 系统编程课程再加: 第 10 至 12 章,一步步构建出一个并发 Web 服务器。
  • 计算机组成课程再加: 第 4 章处理器体系结构。
  • 练习: 每个概念出现时就做相应的练习题,并尝试完成实验,尤其是数据、炸弹、缓冲区溢出、缓存、shell 和 malloc 实验。手边最好备一台 Linux 机器或虚拟机。

课程实例:卡内基梅隆大学 15-213

  • 课程: 卡内基梅隆大学 15-213/15-513/14-513 Introduction to Computer Systems,2025 年秋季(教学大纲)。
  • 角色: CS:APP3e 是必读的主要教材,所有阅读作业都出自本书。课程要求学生阅读正文,并尝试完成每次课阅读内容所对应的练习题。也就是说,本书是配合练习使用的工作教材,而不只是参考书。
  • 获取: CMU 的 15-213/15-513 教材页面说明,CMU 图书馆提供本书。
  • 主题: 课程主题包括数值表示与位级运算、C 与汇编的关系、二进制级调试、进程与线程、虚拟内存、网络、内存与 CPU 性能、安全漏洞、编程工具,以及同步。具体到哪些章节,以课程进度表为准。
  • 配套参考: 课程建议以 Kernighan 和 Ritchie 的 The C Programming Language(第 2 版,1988)作为 C 语言参考书,而不是作为替代的系统教材。
  • 版本: 课程指定第三版(Pearson,ISBN 0-13-409266-X),并倾向于精装本。

版本与书目来源

本页介绍的是北美第三版。作者记录其发行时间为 2015 年 3 月,版权年为 2016 年;上文引用采用发行年。Global 版的页码和书号不同。公开的实验和样章并不意味着整本教材可以免费获取。

ISBN 978-0-13-409266-9 是 CMU 所指定的 0-13-409266-X 的 13 位形式,因此与上述 CMU 课程使用的是同一版本;CMU 引用的 2016 年是该版的版权年。平装本/国际版的习题差异见上文“局限”部分。

第三版的官方介绍见作者网站。