電腦科學

計算機系統:程式設計師的視角

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 語言參考書,而非替代的系統教材。大綱未列正式先修課程。
  • 版本: 兩份 CMU 文件都指定第三版(Pearson,ISBN 0-13-409266-X),並偏好精裝本。

版本與書目來源

所列 ISBN 為北美第 3 版,2015 年 3 月發行,版權年為 2016;此處標注的是發行年。Global 版的頁碼和書號不同;公開的實驗或樣章並不代表整本書可免費取得。

ISBN 978-0-13-409266-9 即 CMU 所指定 0-13-409266-X 的 13 位數形式,因此與上述 CMU 課程使用的是同一版本;CMU 標示的 2016 年是該版的版權年。若跟隨課程做習題,請留意前文提到的平裝本/國際版題目差異。

版本資訊見作者的第三版說明頁。