索引 / 001 ZH-CN
计算机系统:程序员的视角 cover

计算机科学

计算机科学

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

Randal E. Bryant and David R. O'Hallaron

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

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

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

难度等级
中级
学术层次
本科
计算机系统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 年,处理器和缓存示例反映的是当时的机器。

在课程中的定位

《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 机器或虚拟机。