如何閱讀《深入理解計(jì)算機(jī)系統(tǒng)》(文末抽獎(jiǎng)送書(shū))
作者:Randal E. Bryant,David R. O'Hallaron
來(lái)源:華章計(jì)算機(jī)(hzbook_jsj)

《深入理解計(jì)算機(jī)系統(tǒng)》(簡(jiǎn)稱(chēng)CS:APP)的主要讀者是計(jì)算機(jī)科學(xué)家、計(jì)算機(jī)工程師,以及那些想通過(guò)學(xué)習(xí)計(jì)算機(jī)系統(tǒng)的內(nèi)在運(yùn)作而能夠?qū)懗龈贸绦虻娜恕?/span>
我們的目的是解釋所有計(jì)算機(jī)系統(tǒng)的本質(zhì)概念,并向你展示這些概念是如何實(shí)實(shí)在在地影響應(yīng)用程序的正確性、性能和實(shí)用性的。其他的系統(tǒng)類(lèi)書(shū)籍都是從構(gòu)建者的角度來(lái)寫(xiě)的,講述如何實(shí)現(xiàn)硬件或系統(tǒng)軟件,包括操作系統(tǒng)、編譯器和網(wǎng)絡(luò)接口。而本書(shū)是從程序員的角度來(lái)寫(xiě)的,講述應(yīng)用程序員如何能夠利用系統(tǒng)知識(shí)來(lái)編寫(xiě)出更好的程序。當(dāng)然,學(xué)習(xí)一個(gè)計(jì)算機(jī)系統(tǒng)應(yīng)該做些什么,是學(xué)習(xí)如何構(gòu)建一個(gè)計(jì)算機(jī)系統(tǒng)的很好的出發(fā)點(diǎn),所以,對(duì)于希望繼續(xù)學(xué)習(xí)系統(tǒng)軟硬件實(shí)現(xiàn)的人來(lái)說(shuō),本書(shū)也是一本很有價(jià)值的介紹性讀物。大多數(shù)系統(tǒng)書(shū)籍還傾向于重點(diǎn)關(guān)注系統(tǒng)的某一個(gè)方面,比如:硬件架構(gòu)、操作系統(tǒng)、編譯器或者網(wǎng)絡(luò)。本書(shū)則以程序員的視角統(tǒng)一覆蓋了上述所有方面的內(nèi)容。
如果你研究和領(lǐng)會(huì)了這本書(shū)里的概念,你將開(kāi)始成為極少數(shù)的“牛人”,這些“牛人”知道事情是如何運(yùn)作的,也知道當(dāng)事情出現(xiàn)故障時(shí)如何修復(fù)。你寫(xiě)的程序?qū)⒛軌蚋玫乩貌僮飨到y(tǒng)和系統(tǒng)軟件提供的功能,對(duì)各種操作條件和運(yùn)行時(shí)參數(shù)都能正確操作,運(yùn)行起來(lái)更快,并能避免出現(xiàn)使程序容易受到網(wǎng)絡(luò)攻擊的缺陷。同時(shí),你也要做好更深入探究的準(zhǔn)備,研究像編譯器、計(jì)算機(jī)體系結(jié)構(gòu)、操作系統(tǒng)、嵌入式系統(tǒng)、網(wǎng)絡(luò)互聯(lián)和網(wǎng)絡(luò)安全這樣的高級(jí)題目。
本書(shū)的重點(diǎn)是執(zhí)行x86-64機(jī)器代碼的系統(tǒng)。對(duì)英特爾及其競(jìng)爭(zhēng)對(duì)手而言,x86-64是他們自1978年起,以8086微處理器為代表,不斷進(jìn)化的最新成果。按照英特爾微處理器產(chǎn)品線(xiàn)的命名規(guī)則,這類(lèi)微處理器俗稱(chēng)為“x86”。隨著半導(dǎo)體技術(shù)的演進(jìn),單芯片上集成了更多的晶體管,這些處理器的計(jì)算能力和內(nèi)存容量有了很大的增長(zhǎng)。在這個(gè)過(guò)程中,它們從處理16位字,發(fā)展到引入IA32處理器處理32位字,再到最近的x86-64處理64位字。
我們考慮的是這些機(jī)器如何在Linux操作系統(tǒng)上運(yùn)行C語(yǔ)言程序。Linux是眾多繼承自最初由貝爾實(shí)驗(yàn)室開(kāi)發(fā)的Unix的操作系統(tǒng)中的一種。這類(lèi)操作系統(tǒng)的其他成員包括Solaris、FreeBSD和MacOS X。近年來(lái),由于Posix和標(biāo)準(zhǔn)Unix規(guī)范的標(biāo)準(zhǔn)化努力,這些操作系統(tǒng)保持了高度兼容性。因此,本書(shū)內(nèi)容幾乎直接適用于這些“類(lèi)Unix”操作系統(tǒng)。
文中包含大量已在Linux系統(tǒng)上編譯和運(yùn)行過(guò)的程序示例。我們假設(shè)你能訪(fǎng)問(wèn)一臺(tái)這樣的機(jī)器,并且能夠登錄,做一些諸如切換目錄之類(lèi)的簡(jiǎn)單操作。如果你的計(jì)算機(jī)運(yùn)行的是Microsoft Windows系統(tǒng),我們建議你選擇安裝一個(gè)虛擬機(jī)環(huán)境(例如VirtualBox或者VMWare),以便為一種操作系統(tǒng)(客戶(hù)OS)編寫(xiě)的程序能在另一種系統(tǒng)(宿主OS)上運(yùn)行。
我們還假設(shè)你對(duì)C和C++有一定的了解。如果你以前只有Java經(jīng)驗(yàn),那么你需要付出更多的努力來(lái)完成這種轉(zhuǎn)換,不過(guò)我們也會(huì)幫助你。Java和C有相似的語(yǔ)法和控制語(yǔ)句。不過(guò),有一些C語(yǔ)言的特性(特別是指針、顯式的動(dòng)態(tài)內(nèi)存分配和格式化I/O)在Java中都是沒(méi)有的。所幸的是,C是一個(gè)較小的語(yǔ)言,在Brian Kernighan和Dennis Ritchie經(jīng)典的“K&R”文獻(xiàn)中得到了清晰優(yōu)美的描述。無(wú)論你的編程背景如何,都應(yīng)該考慮將K&R作為個(gè)人系統(tǒng)藏書(shū)的一部分。如果你只有使用解釋性語(yǔ)言的經(jīng)驗(yàn),如Python、Ruby或Perl,那么在使用本書(shū)之前,需要花費(fèi)一些時(shí)間來(lái)學(xué)習(xí)C。
本書(shū)的前幾章揭示了C語(yǔ)言程序和它們相對(duì)應(yīng)的機(jī)器語(yǔ)言程序之間的交互作用。機(jī)器語(yǔ)言示例都是用運(yùn)行在x86-64處理器上的GNU GCC編譯器生成的。我們不需要你以前有任何硬件、機(jī)器語(yǔ)言或是匯編語(yǔ)言編程的經(jīng)驗(yàn)。
給C語(yǔ)言初學(xué)者 關(guān)于C編程語(yǔ)言的建議
為了幫助C語(yǔ)言編程背景薄弱(或全無(wú)背景)的讀者,我們?cè)跁?shū)中加入了這樣一些專(zhuān)門(mén)的注釋來(lái)突出C中一些特別重要的特性。我們假設(shè)你熟悉C++或Java。
從程序員的角度學(xué)習(xí)計(jì)算機(jī)系統(tǒng)是如何工作的會(huì)非常有趣,主要是因?yàn)槟憧梢灾鲃?dòng)地做這件事情。無(wú)論何時(shí)你學(xué)到一些新的東西,都可以馬上試驗(yàn)并且直接看到運(yùn)行結(jié)果。事實(shí)上,我們相信學(xué)習(xí)系統(tǒng)的唯一方法就是做(do)系統(tǒng),即在真正的系統(tǒng)上解決具體的問(wèn)題,或是編寫(xiě)和運(yùn)行程序。
這個(gè)主題觀念貫穿全書(shū)。當(dāng)引入一個(gè)新概念時(shí),將會(huì)有一個(gè)或多個(gè)練習(xí)題緊隨其后,你應(yīng)該馬上做一做來(lái)檢驗(yàn)?zāi)愕睦斫狻_@些練習(xí)題的解答在每章的末尾。當(dāng)你閱讀時(shí),嘗試自己來(lái)解答每個(gè)問(wèn)題,然后再查閱答案,看自己的答案是否正確。除第1章外,每章后面都有難度不同的家庭作業(yè)。對(duì)每個(gè)家庭作業(yè)題,我們標(biāo)注了難度級(jí)別:
只需要幾分鐘。幾乎或完全不需要編程。








文中每段代碼示例都是由經(jīng)過(guò)GCC編譯的C程序直接生成并在Linux系統(tǒng)上進(jìn)行了測(cè)試,沒(méi)有任何人為的改動(dòng)。當(dāng)然,你的系統(tǒng)上GCC的版本可能不同,或者根本就是另外一種編譯器,那么可能生成不一樣的機(jī)器代碼,但是整體行為表現(xiàn)應(yīng)該是一樣的。所有的源程序代碼都可以從csapp.cs.cmu.edu上的CS:APP主頁(yè)上獲取。在本書(shū)中,源程序的文件名列在兩條水平線(xiàn)的右邊,水平線(xiàn)之間是格式化的代碼。比如,圖1中的程序能在code/intro/目錄下的hello.c文件中找到。當(dāng)遇到這些示例程序時(shí),我們鼓勵(lì)你在自己的系統(tǒng)上試著運(yùn)行它們。

為了避免本書(shū)體積過(guò)大、內(nèi)容過(guò)多,我們添加了許多網(wǎng)絡(luò)旁注(Web aside),包括一些對(duì)本書(shū)主要內(nèi)容的補(bǔ)充資料。本書(shū)中用CHAP:TOP這樣的標(biāo)記形式來(lái)引用這些旁注,這里CHAP是該章主題的縮寫(xiě)編碼,而TOP是涉及的話(huà)題的縮寫(xiě)編碼。例如,網(wǎng)絡(luò)旁注DATA:BOOL包含對(duì)第2章中數(shù)據(jù)表示里面有關(guān)布爾代數(shù)內(nèi)容的補(bǔ)充資料;而網(wǎng)絡(luò)旁注ARCH:VLOG包含的是用Verilog硬件描述語(yǔ)言進(jìn)行處理器設(shè)計(jì)的資料,是對(duì)第4章中處理器設(shè)計(jì)部分的補(bǔ)充。所有的網(wǎng)絡(luò)旁注都可以從CS:APP的主頁(yè)上獲取。
什么是旁注?
在整本書(shū)中,你將會(huì)遇到很多以這種形式出現(xiàn)的旁注。旁注是附加說(shuō)明,能使你對(duì)當(dāng)前討論的主題多一些了解。旁注可以有很多用處。一些是小的歷史故事。例如,C語(yǔ)言、Linux和Internet是從何而來(lái)的?有些旁注則是用來(lái)澄清學(xué)生們經(jīng)常感到疑惑的問(wèn)題。例如,高速緩存的行、組和塊有什么區(qū)別?還有些旁注給出了一些現(xiàn)實(shí)世界的例子。例如,一個(gè)浮點(diǎn)錯(cuò)誤怎么毀掉了法國(guó)的一枚火箭,或是給出市面上出售的一個(gè)磁盤(pán)驅(qū)動(dòng)器的幾何和運(yùn)行參數(shù)。最后,還有一些旁注僅僅就是一些有趣的內(nèi)容,例如,什么是“hoinky”?
本書(shū)由12章組成,旨在闡述計(jì)算機(jī)系統(tǒng)的核心概念。內(nèi)容概述如下:
第1章:計(jì)算機(jī)系統(tǒng)漫游。這一章通過(guò)研究“hello,world”這個(gè)簡(jiǎn)單程序的生命周期,介紹計(jì)算機(jī)系統(tǒng)的主要概念和主題。
第2章:信息的表示和處理。我們講述了計(jì)算機(jī)的算術(shù)運(yùn)算,重點(diǎn)描述了會(huì)對(duì)程序員有影響的無(wú)符號(hào)數(shù)和數(shù)的補(bǔ)碼表示的特性。我們考慮數(shù)字是如何表示的,以及由此確定對(duì)于一個(gè)給定的字長(zhǎng),其可能編碼值的范圍。我們探討有符號(hào)和無(wú)符號(hào)數(shù)字之間類(lèi)型轉(zhuǎn)換的效果,還闡述算術(shù)運(yùn)算的數(shù)學(xué)特性。菜鳥(niǎo)級(jí)程序員經(jīng)常很驚奇地了解到(用補(bǔ)碼表示的)兩個(gè)正數(shù)的和或者積可能為負(fù)。另一方面,補(bǔ)碼的算術(shù)運(yùn)算滿(mǎn)足很多整數(shù)運(yùn)算的代數(shù)特性,因此,編譯器可以很安全地把一個(gè)常量乘法轉(zhuǎn)化為一系列的移位和加法。我們用C語(yǔ)言的位級(jí)操作來(lái)說(shuō)明布爾代數(shù)的原理和應(yīng)用。我們從兩個(gè)方面講述了IEEE標(biāo)準(zhǔn)的浮點(diǎn)格式:一是如何用它來(lái)表示數(shù)值,一是浮點(diǎn)運(yùn)算的數(shù)學(xué)屬性。
對(duì)計(jì)算機(jī)的算術(shù)運(yùn)算有深刻的理解是寫(xiě)出可靠程序的關(guān)鍵。比如,程序員和編譯器不能用表達(dá)式(x-y<0)來(lái)替代(x<y),因?yàn)榍罢呖赡軙?huì)產(chǎn)生溢出。甚至也不能用表達(dá)式(-y<-x)來(lái)替代,因?yàn)樵谘a(bǔ)碼表示中負(fù)數(shù)和正數(shù)的范圍是不對(duì)稱(chēng)的。算術(shù)溢出是造成程序錯(cuò)誤和安全漏洞的一個(gè)常見(jiàn)根源,然而很少有書(shū)從程序員的角度來(lái)講述計(jì)算機(jī)算術(shù)運(yùn)算的特性。
第3章:程序的機(jī)器級(jí)表示。我們教讀者如何閱讀由C編譯器生成的x86-64機(jī)器代碼。我們說(shuō)明為不同控制結(jié)構(gòu)(比如條件、循環(huán)和開(kāi)關(guān)語(yǔ)句)生成的基本指令模式。我們還講述過(guò)程的實(shí)現(xiàn),包括棧分配、寄存器使用慣例和參數(shù)傳遞。我們討論不同數(shù)據(jù)結(jié)構(gòu)(如結(jié)構(gòu)、聯(lián)合和數(shù)組)的分配和訪(fǎng)問(wèn)方式。我們還說(shuō)明實(shí)現(xiàn)整數(shù)和浮點(diǎn)數(shù)算術(shù)運(yùn)算的指令。我們還以分析程序在機(jī)器級(jí)的樣子作為途徑,來(lái)理解常見(jiàn)的代碼安全漏洞(例如緩沖區(qū)溢出),以及理解程序員、編譯器和操作系統(tǒng)可以采取的減輕這些威脅的措施。學(xué)習(xí)本章的概念能夠幫助讀者成為更好的程序員,因?yàn)槟銈兌贸绦蛟跈C(jī)器上是如何表示的。另外一個(gè)好處就在于讀者會(huì)對(duì)指針有非常全面而具體的理解。
第4章:處理器體系結(jié)構(gòu)。這一章講述基本的組合和時(shí)序邏輯元素,并展示這些元素如何在數(shù)據(jù)通路中組合到一起,來(lái)執(zhí)行x86-64指令集的一個(gè)稱(chēng)為“Y86-64”的簡(jiǎn)化子集。我們從設(shè)計(jì)單時(shí)鐘周期數(shù)據(jù)通路開(kāi)始。這個(gè)設(shè)計(jì)概念上非常簡(jiǎn)單,但是運(yùn)行速度不會(huì)太快。然后我們引入流水線(xiàn)的思想,將處理一條指令所需要的不同步驟實(shí)現(xiàn)為獨(dú)立的階段。這個(gè)設(shè)計(jì)中,在任何時(shí)刻,每個(gè)階段都可以處理不同的指令。我們的五階段處理器流水線(xiàn)更加實(shí)用。本章中處理器設(shè)計(jì)的控制邏輯是用一種稱(chēng)為HCL的簡(jiǎn)單硬件描述語(yǔ)言來(lái)描述的。用HCL寫(xiě)的硬件設(shè)計(jì)能夠編譯和鏈接到本書(shū)提供的模擬器中,還可以根據(jù)這些設(shè)計(jì)生成Verilog描述,它適合合成到實(shí)際可以運(yùn)行的硬件上去。
第5章:優(yōu)化程序性能。在這一章里,我們介紹了許多提高代碼性能的技術(shù),主要思想就是讓程序員通過(guò)使編譯器能夠生成更有效的機(jī)器代碼來(lái)學(xué)習(xí)編寫(xiě)C代碼。我們一開(kāi)始介紹的是減少程序需要做的工作的變換,這些是在任何機(jī)器上寫(xiě)任何程序時(shí)都應(yīng)該遵循的。然后講的是增加生成的機(jī)器代碼中指令級(jí)并行度的變換,因而提高了程序在現(xiàn)代“超標(biāo)量”處理器上的性能。為了解釋這些變換行之有效的原理,我們介紹了一個(gè)簡(jiǎn)單的操作模型,它描述了現(xiàn)代亂序處理器是如何工作的,然后給出了如何根據(jù)一個(gè)程序的圖形化表示中的關(guān)鍵路徑來(lái)測(cè)量一個(gè)程序可能的性能。你會(huì)驚訝于對(duì)C代碼做一些簡(jiǎn)單的變換能給程序帶來(lái)多大的速度提升。
第6章:存儲(chǔ)器層次結(jié)構(gòu)。對(duì)應(yīng)用程序員來(lái)說(shuō),存儲(chǔ)器系統(tǒng)是計(jì)算機(jī)系統(tǒng)中最直接可見(jiàn)的部分之一。到目前為止,讀者一直認(rèn)同這樣一個(gè)存儲(chǔ)器系統(tǒng)概念模型,認(rèn)為它是一個(gè)有一致訪(fǎng)問(wèn)時(shí)間的線(xiàn)性數(shù)組。實(shí)際上,存儲(chǔ)器系統(tǒng)是一個(gè)由不同容量、造價(jià)和訪(fǎng)問(wèn)時(shí)間的存儲(chǔ)設(shè)備組成的層次結(jié)構(gòu)。我們講述不同類(lèi)型的隨機(jī)存取存儲(chǔ)器(RAM)和只讀存儲(chǔ)器(ROM),以及磁盤(pán)和固態(tài)硬盤(pán) (直譯應(yīng)為固態(tài)驅(qū)動(dòng)器,但固態(tài)硬盤(pán)一詞已經(jīng)被大家接受,所以沿用。——譯者注)的幾何形狀和組織構(gòu)造。我們描述這些存儲(chǔ)設(shè)備是如何放置在層次結(jié)構(gòu)中的,講述訪(fǎng)問(wèn)局部性是如何使這種層次結(jié)構(gòu)成為可能的。我們通過(guò)一個(gè)獨(dú)特的觀點(diǎn)使這些理論具體化,那就是將存儲(chǔ)器系統(tǒng)視為一個(gè)“存儲(chǔ)器山”,山脊是時(shí)間局部性,而斜坡是空間局部性。最后,我們向讀者闡述如何通過(guò)改善程序的時(shí)間局部性和空間局部性來(lái)提高應(yīng)用程序的性能。
第7章:鏈接。本章講述靜態(tài)和動(dòng)態(tài)鏈接,包括的概念有可重定位的和可執(zhí)行的目標(biāo)文件、符號(hào)解析、重定位、靜態(tài)庫(kù)、共享目標(biāo)庫(kù)、位置無(wú)關(guān)代碼,以及庫(kù)打樁。大多數(shù)講述系統(tǒng)的書(shū)中都不講鏈接,我們要講述它是出于以下原因。第一,程序員遇到的最令人迷惑的問(wèn)題中,有一些和鏈接時(shí)的小故障有關(guān),尤其是對(duì)那些大型軟件包來(lái)說(shuō)。第二,鏈接器生成的目標(biāo)文件是與一些像加載、虛擬內(nèi)存和內(nèi)存映射這樣的概念相關(guān)的。
第8章:異常控制流。在本書(shū)的這個(gè)部分,我們通過(guò)介紹異常控制流(即除正常分支和過(guò)程調(diào)用以外的控制流的變化)的一般概念,打破單一程序的模型。我們給出存在于系統(tǒng)所有層次的異常控制流的例子,從底層的硬件異常和中斷,到并發(fā)進(jìn)程的上下文切換,到由于接收Linux信號(hào)引起的控制流突變,到C語(yǔ)言中破壞棧原則的非本地跳轉(zhuǎn)。
在這一章,我們介紹進(jìn)程的基本概念,進(jìn)程是對(duì)一個(gè)正在執(zhí)行的程序的一種抽象。讀者會(huì)學(xué)習(xí)進(jìn)程是如何工作的,以及如何在應(yīng)用程序中創(chuàng)建和操縱進(jìn)程。我們會(huì)展示應(yīng)用程序員如何通過(guò)Linux系統(tǒng)調(diào)用來(lái)使用多個(gè)進(jìn)程。學(xué)完本章之后,讀者就能夠編寫(xiě)帶作業(yè)控制的Linux shell了。同時(shí),這里也會(huì)向讀者初步展示程序的并發(fā)執(zhí)行會(huì)引起不確定的行為。
第9章:虛擬內(nèi)存。我們講述虛擬內(nèi)存系統(tǒng)是希望讀者對(duì)它是如何工作的以及它的特性有所了解。我們想讓讀者了解為什么不同的并發(fā)進(jìn)程各自都有一個(gè)完全相同的地址范圍,能共享某些頁(yè),而又獨(dú)占另外一些頁(yè)。我們還講了一些管理和操縱虛擬內(nèi)存的問(wèn)題。特別地,我們討論了存儲(chǔ)分配操作,就像標(biāo)準(zhǔn)庫(kù)的malloc和free操作。闡述這些內(nèi)容是出于下面幾個(gè)目的。它加強(qiáng)了這樣一個(gè)概念,那就是虛擬內(nèi)存空間只是一個(gè)字節(jié)數(shù)組,程序可以把它劃分成不同的存儲(chǔ)單元。它可以幫助讀者理解當(dāng)程序包含存儲(chǔ)泄漏和非法指針引用等內(nèi)存引用錯(cuò)誤時(shí)的后果。最后,許多應(yīng)用程序員編寫(xiě)自己的優(yōu)化了的存儲(chǔ)分配操作來(lái)滿(mǎn)足應(yīng)用程序的需要和特性。這一章比其他任何一章都更能展現(xiàn)將計(jì)算機(jī)系統(tǒng)中的硬件和軟件結(jié)合起來(lái)闡述的優(yōu)點(diǎn)。而傳統(tǒng)的計(jì)算機(jī)體系結(jié)構(gòu)和操作系統(tǒng)書(shū)籍都只講述虛擬內(nèi)存的某一方面。
第10章:系統(tǒng)級(jí)I/O。我們講述Unix I/O的基本概念,例如文件和描述符。我們描述如何共享文件,I/O重定向是如何工作的,還有如何訪(fǎng)問(wèn)文件的元數(shù)據(jù)。我們還開(kāi)發(fā)了一個(gè)健壯的帶緩沖區(qū)的I/O包,可以正確處理一種稱(chēng)為short counts的奇特行為,也就是庫(kù)函數(shù)只讀取一部分的輸入數(shù)據(jù)。我們闡述C的標(biāo)準(zhǔn)I/O庫(kù),以及它與Linux I/O的關(guān)系,重點(diǎn)談到標(biāo)準(zhǔn)I/O的局限性,這些局限性使之不適合網(wǎng)絡(luò)編程。總的來(lái)說(shuō),本章的主題是后面兩章——網(wǎng)絡(luò)和并發(fā)編程的基礎(chǔ)。
第11章:網(wǎng)絡(luò)編程。對(duì)編程而言,網(wǎng)絡(luò)是非常有趣的I/O設(shè)備,它將許多我們前面文中學(xué)習(xí)的概念(比如進(jìn)程、信號(hào)、字節(jié)順序、內(nèi)存映射和動(dòng)態(tài)內(nèi)存分配)聯(lián)系在一起。網(wǎng)絡(luò)程序還為下一章的主題——并發(fā),提供了一個(gè)很令人信服的上下文。本章只是網(wǎng)絡(luò)編程的一個(gè)很小的部分,使讀者能夠編寫(xiě)一個(gè)簡(jiǎn)單的Web服務(wù)器。我們還講述位于所有網(wǎng)絡(luò)程序底層的客戶(hù)端服務(wù)器模型。我們展現(xiàn)了一個(gè)程序員對(duì)Internet的觀點(diǎn),并且教讀者如何用套接字接口來(lái)編寫(xiě)Internet客戶(hù)端和服務(wù)器。最后,我們介紹超文本傳輸協(xié)議(HTTP),并開(kāi)發(fā)了一個(gè)簡(jiǎn)單的迭代式Web服務(wù)器。
第12章:并發(fā)編程。這一章以Internet服務(wù)器設(shè)計(jì)為例介紹了并發(fā)編程。我們比較對(duì)照了三種編寫(xiě)并發(fā)程序的基本機(jī)制(進(jìn)程、I/O多路復(fù)用和線(xiàn)程),并且展示如何用它們來(lái)建造并發(fā)Internet服務(wù)器。我們探討了用P、V信號(hào)量操作來(lái)實(shí)現(xiàn)同步、線(xiàn)程安全和可重入、競(jìng)爭(zhēng)條件以及死鎖等的基本原則。對(duì)大多數(shù)服務(wù)器應(yīng)用來(lái)說(shuō),寫(xiě)并發(fā)代碼都是很關(guān)鍵的。我們還講述了線(xiàn)程級(jí)編程的使用方法,用這種方法來(lái)表達(dá)應(yīng)用程序中的并行性,使得程序在多核處理器上能執(zhí)行得更快。使用所有的核解決同一個(gè)計(jì)算問(wèn)題需要很小心謹(jǐn)慎地協(xié)調(diào)并發(fā)線(xiàn)程,既要保證正確性,又要爭(zhēng)取獲得高性能。
本書(shū)的第1版于2003年出版,第2版在2011年出版。考慮到計(jì)算機(jī)技術(shù)發(fā)展如此迅速,這本書(shū)的內(nèi)容還算是保持得很好。事實(shí)證明Intel x86的機(jī)器上運(yùn)行Linux(以及相關(guān)操作系統(tǒng)),加上采用C語(yǔ)言編程,是一種能夠涵蓋當(dāng)今許多系統(tǒng)的組合。然而,硬件技術(shù)、編譯器和程序庫(kù)接口的變化,以及很多教師教授這些內(nèi)容的經(jīng)驗(yàn),都促使我們做了大量的修改。
第2版以來(lái)的最大整體變化是,我們的介紹從以IA32和x86-64為基礎(chǔ),轉(zhuǎn)變?yōu)橥耆?span style="font-family: Calibri;">x86-64為基礎(chǔ)。這種重心的轉(zhuǎn)移影響了很多章節(jié)的內(nèi)容。下面列出一些明顯的變化:
第1章。我們將第5章對(duì)Amdahl定理的討論移到了本章。
第2章。讀者和評(píng)論家的反饋是一致的,本章的一些內(nèi)容有點(diǎn)令人不知所措。因此,我們澄清了一些知識(shí)點(diǎn),用更加數(shù)學(xué)的方式來(lái)描述,使得這些內(nèi)容更容易理解。這使得讀者能先略過(guò)數(shù)學(xué)細(xì)節(jié),獲得高層次的總體概念,然后回過(guò)頭來(lái)進(jìn)行更細(xì)致深入的閱讀。
第3章。我們將之前基于IA32和x86-64的表現(xiàn)形式轉(zhuǎn)換為完全基于x86-64,還更新了近期版本GCC產(chǎn)生的代碼。其結(jié)果是大量的重寫(xiě)工作,包括修改了一些概念提出的順序。同時(shí),我們還首次介紹了對(duì)處理浮點(diǎn)數(shù)據(jù)的程序的機(jī)器級(jí)支持。由于歷史原因,我們給出了一個(gè)網(wǎng)絡(luò)旁注描述IA32機(jī)器碼。
第4章。我們將之前基于32位架構(gòu)的處理器設(shè)計(jì)修改為支持64位字和操作的設(shè)計(jì)。
第5章。我們更新了內(nèi)容以反映最近幾代x86-64處理器的性能。通過(guò)引入更多的功能單元和更復(fù)雜的控制邏輯,我們開(kāi)發(fā)的基于程序數(shù)據(jù)流表示的程序性能模型,其性能預(yù)測(cè)變得比之前更加可靠。
第6章。我們對(duì)內(nèi)容進(jìn)行了更新,以反映更多的近期技術(shù)。
第7章。針對(duì)x86-64,我們重寫(xiě)了本章,擴(kuò)充了關(guān)于用GOT和PLT創(chuàng)建位置無(wú)關(guān)代碼的討論,新增了一節(jié)描述更加強(qiáng)大的鏈接技術(shù),比如庫(kù)打樁。
第8章。我們?cè)黾恿藢?duì)信號(hào)處理程序更細(xì)致的描述,包括異步信號(hào)安全的函數(shù),編寫(xiě)信號(hào)處理程序的具體指導(dǎo)原則,以及用sigsuspend等待處理程序。
第9章。本章變化不大。
第10章。我們新增了一節(jié)說(shuō)明文件和文件的層次結(jié)構(gòu),除此之外,本章的變化不大。
第11章。我們介紹了采用最新getaddrinfo和getnameinfo函數(shù)的、與協(xié)議無(wú)關(guān)和線(xiàn)程安全的網(wǎng)絡(luò)編程,取代過(guò)時(shí)的、不可重入的gethostbyname和gethostbyaddr函數(shù)。
第12章。我們擴(kuò)充了利用線(xiàn)程級(jí)并行性使得程序在多核機(jī)器上更快運(yùn)行的內(nèi)容。
此外,我們還增加和修改了很多練習(xí)題和家庭作業(yè)。
本書(shū)起源于1998年秋季,我們?cè)诳▋?nèi)基梅隆(CMU)大學(xué)開(kāi)設(shè)的一門(mén)編號(hào)為15-213的介紹性課程:計(jì)算機(jī)系統(tǒng)導(dǎo)論(Introduction to Computer System,ICS)。從那以后,每學(xué)期都開(kāi)設(shè)了ICS這門(mén)課程,每學(xué)期有超過(guò)400名學(xué)生上課,這些學(xué)生從本科二年級(jí)到碩士研究生都有,所學(xué)專(zhuān)業(yè)也很廣泛。這門(mén)課程是卡內(nèi)基梅隆大學(xué)計(jì)算機(jī)科學(xué)系(CS)以及電子和計(jì)算機(jī)工程系(ECE)所有本科生的必修課,也是CS和ECE大多數(shù)高級(jí)系統(tǒng)課程的先行必修課。
ICS這門(mén)課程的宗旨是用一種不同的方式向?qū)W生介紹計(jì)算機(jī)。因?yàn)椋覀兊膶W(xué)生中幾乎沒(méi)有人有機(jī)會(huì)親自去構(gòu)造一個(gè)計(jì)算機(jī)系統(tǒng)。另一方面,大多數(shù)學(xué)生,甚至包括所有的計(jì)算機(jī)科學(xué)家和計(jì)算機(jī)工程師,也需要日常使用計(jì)算機(jī)和編寫(xiě)計(jì)算機(jī)程序。所以我們決定從程序員的角度來(lái)講解系統(tǒng),并采用這樣的原則過(guò)濾要講述的內(nèi)容:我們只討論那些影響用戶(hù)級(jí)C語(yǔ)言程序的性能、正確性或?qū)嵱眯缘闹黝}。
比如,我們排除了諸如硬件加法器和總線(xiàn)設(shè)計(jì)這樣的主題。雖然我們談及了機(jī)器語(yǔ)言,但是重點(diǎn)并不在于如何手工編寫(xiě)匯編語(yǔ)言,而是關(guān)注C語(yǔ)言編譯器是如何將C語(yǔ)言的結(jié)構(gòu)翻譯成機(jī)器代碼的,包括編譯器是如何翻譯指針、循環(huán)、過(guò)程調(diào)用以及開(kāi)關(guān)(switch)語(yǔ)句的。更進(jìn)一步地,我們將更廣泛和全盤(pán)地看待系統(tǒng),包括硬件和系統(tǒng)軟件,涵蓋了包括鏈接、加載、進(jìn)程、信號(hào)、性能優(yōu)化、虛擬內(nèi)存、I/O以及網(wǎng)絡(luò)與并發(fā)編程等在內(nèi)的主題。
這種做法使得我們講授ICS課程的方式對(duì)學(xué)生來(lái)講既實(shí)用、具體,還能動(dòng)手操作,同時(shí)也非常能調(diào)動(dòng)學(xué)生的積極性。很快地,我們收到來(lái)自學(xué)生和教職工非常熱烈而積極的反響,我們意識(shí)到卡內(nèi)基梅隆大學(xué)以外的其他人也可以從我們的方法中獲益。因此,這本書(shū)從ICS課程的筆記中應(yīng)運(yùn)而生了,而現(xiàn)在我們對(duì)它做了修改,使之能夠反映科學(xué)技術(shù)以及計(jì)算機(jī)系統(tǒng)實(shí)現(xiàn)中的變化和進(jìn)步。
通過(guò)本書(shū)的多個(gè)版本和多種語(yǔ)言譯本,ICS和許多相似課程已經(jīng)成為世界范圍內(nèi)數(shù)百所高校的計(jì)算機(jī)科學(xué)和計(jì)算機(jī)工程課程的一部分。
本文摘編自《深入理解計(jì)算機(jī)系統(tǒng)(原書(shū)第3版)》,經(jīng)出版方授權(quán)發(fā)布。

作者:[美] 蘭德?tīng)?E.布萊恩特(Randal E. Bryant)
大衛(wèi) R. 奧哈拉倫(David R. O'Hallaron)
譯者:龔奕利、賀蓮
被譽(yù)為“價(jià)值超過(guò)等重量黃金的無(wú)價(jià)資源寶庫(kù)”理解計(jì)算機(jī)系統(tǒng)首選書(shū)目, 十余萬(wàn)程序員的共同選擇。
本書(shū)是一本將計(jì)算機(jī)軟件和硬件理論結(jié)合講述的經(jīng)典教程,內(nèi)容覆蓋計(jì)算機(jī)導(dǎo)論、體系結(jié)構(gòu)和處理器設(shè)計(jì)等多門(mén)課程。卡內(nèi)基-梅隆大學(xué)、北京大學(xué)、上海交大等國(guó)內(nèi)外眾多知名高校選用指定教材。本書(shū)的最大優(yōu)點(diǎn)是為程序員描述計(jì)算機(jī)系統(tǒng)的實(shí)現(xiàn)細(xì)節(jié),通過(guò)描述程序是如何映射到系統(tǒng)上,以及程序是如何執(zhí)行的,使讀者更好地理解程序的行為,以及造成效率低下的原因。
如何使用本書(shū)從程序員的角度來(lái)學(xué)習(xí)計(jì)算機(jī)系統(tǒng)是如何工作的會(huì)非常有趣。最理想的學(xué)習(xí)方法是在真正的系統(tǒng)上解決具體的問(wèn)題,或是編寫(xiě)和運(yùn)行程序。這個(gè)主題觀念貫穿本書(shū)始終。因此我們建議你用如下方式學(xué)習(xí)這本書(shū):
學(xué)習(xí)一個(gè)新概念時(shí),你應(yīng)該立刻做一做緊隨其后的一個(gè)或多個(gè)練習(xí)題來(lái)檢驗(yàn)?zāi)愕睦斫狻?/span>這些練習(xí)題的解答在每章的末尾。要先嘗試自己來(lái)解答每個(gè)問(wèn)題,然后再查閱答案。
每一章后都有一組難度不同的作業(yè)題,這些題目需要的時(shí)間從十幾分鐘到十幾個(gè)小時(shí),但建議你嘗試完成這些作業(yè)題,完成之后你會(huì)發(fā)現(xiàn)對(duì)系統(tǒng)的理解更加深入。
本書(shū)中有豐富的代碼示例,鼓勵(lì)你在系統(tǒng)上運(yùn)行這些示例的源代碼。
向老師或他人請(qǐng)教和交流是很好的學(xué)習(xí)方式。歡迎加入本書(shū)的讀者群,進(jìn)群交流學(xué)習(xí)

京東開(kāi)學(xué)季大促限時(shí)5折
點(diǎn)擊閱讀全文進(jìn)入大促專(zhuān)題囤書(shū)吧
掃碼關(guān)注【圖書(shū)小編輯】視頻號(hào)
每天來(lái)聽(tīng)華章哥講書(shū)

我們將向讀者免費(fèi)贈(zèng)送兩本《深入理解計(jì)算機(jī)系統(tǒng)》,你只需要點(diǎn)擊下方
抽獎(jiǎng)鏈接,并邀請(qǐng)好友為你助力,將會(huì)有機(jī)會(huì)獲得這本書(shū)!
獲獎(jiǎng)名額有限!想要的朋友們加油分享吧!
活動(dòng)截止時(shí)間:2021年4月11號(hào) 晚8點(diǎn)整
【活動(dòng)方式】
抽獎(jiǎng)鏈接如下:
