1. 程式人生 > >讀完了csapp(中文名:深入理解計算機系統)

讀完了csapp(中文名:深入理解計算機系統)

上個星期終於把csapp看完了。
我買的是中文版的,因為除了貌似評價不錯以外,由於涉及到些自己不瞭解的底層東西,怕是看英文會雲裡霧裡。現在看來,大概不能算是個優點,但是的確能夠加快我的看書速度,否則一星期還真不大可能把這書搞定。

對csapp慕名已久,主要在於據說這本書儘量的做到相對實用,不去講那些和實際程式設計沒多大關係的計算機原理(畢竟是著名計算機院校裡面最偏軟體的cmu的作品),重點非常得當,像我這種沒有本科科班出生又不想去死讀些不知道以後有沒有用的東西的人來說,最是適合了。感興趣的東西就可以再加深,不感興趣的就算了,正好。
在csapp的序言裡有個課程列表,其中推薦了幾種教學課程,對應使用不同的章節。我參考選用的是ICS+的規劃。ICS+的cmu課號為15-213,據說正好和cmu的郵編相同,然後就有了這句“15-213: The Class That Gives CMU Its Zip

!”。以這句為關鍵詞,能夠找到ICS+的slide。
ICS+的課程基本上涵蓋了全書,除了第4章“處理器體系結構”以外。我自己除了跳過這個的確不太感興趣的章節(太偏硬體)以外,還有第9章“測量程式執行時間”是略略翻過,其他的都是認真讀完寫完習題的。

書的確是難得的書。我第一次試圖讀這本書是幾個月以前,當時第2章“資訊的表示和處理”沒看完就放下了,覺得講了一大堆數字表達方式很沒意思……這次稍微堅持了一下,沒想到就一口氣讀下來了……
重點推薦第3章“程式的機器級表示”第5章“優化程式效能”第6章“儲存器層次結構”第10章“虛擬儲存器”。覺得這四章乃是全書之精華,看得人慾罷不能。

“程式的機器級表示”

一章幾乎是一種教授逆向工程的方法在講授,剖析編譯器產生的彙編程式碼,以此來加深對具體程式碼實現的理解。大量的習題都是根據彙編來猜源程式是什麼,有趣極了。這一章還覆蓋了緩衝區攻擊——但是這點講得太少了,不解渴,有時間自己弄弄……
講底層離不了彙編這個有點棘手的東西,我還一度擔心自己彙編學得不太過關,會碰到障礙。但這裡作者提出一個很實際的要求:以前要求程式設計師都會寫彙編,現在要求程式設計師都會讀彙編。這裡以一種“讀”的方式教人用匯編,不侷限於很多細小的語法,讓僅僅懂得C的程式設計師也毫無障礙。僅僅100多頁,不僅初步講了彙編的語法和使用,還配合大量的例子分析來解讀產生的彙編程式碼,讓人理解深刻,實在是技高一籌。

“優化程式效能”是全書最閃光的章節。作者對一個例子不斷優化,講迴圈效率和過程呼叫,到講儲存器引用,一直講到現代處理器的結構,講到IA32處理器的侷限,一路下來,暢快淋漓。還將IA32處理器的優化結果和Compaq Alpha 21164做對比,一目瞭然的看出哪些優化是處理器相關的,最後講到profiling(程式剖析)指導優化,可以說平時能夠用到的最高技巧(畢竟我還不是編譯器開發人員……)和流程走了一邊,現實意義相當之高。
這章把能夠用到的所有技巧的原理全部講解得清清楚楚,不做不必要的挖深,結合程式碼,讓人絲毫不覺枯燥,真是佩服得五體投地。雖然章節後對編譯器優化還提供了參考文獻以及加深的內容,不過我覺得這章的內容已經足夠我受用很久了。

“儲存器層次結構”實際上可以看作是“優化程式效能”一章的延伸,以及為之後的“虛擬儲存器”做鋪墊。這章主要詳細解釋了快取記憶體(cache)的工作方式,以及利用區域性性使得cache達到最好效果的方法。
“虛擬儲存器”(Virtual Memory)則上升到了作業系統層面,詳細解析了VM的實現以及Linux系統上VM組織方式。自己覺得最受用的是malloc/free實現的動態儲存器分配的具體方法以及對程序中具體儲存結構的瞭解,還有GC的策略。這些讓我感覺自己能夠做到的事情似乎又多了一點,一直無法理解的valgrind之類軟體的原理似乎也有了點眉目。
這兩章講得比較細緻,以至於稍微顯得有點枯燥。其實我自己喜歡這兩章的主要原因是解了我多年來關於儲存器的困惑。不過儲存器方面的內容實在博大精深,自己這完全是得了點皮毛就沾沾自喜。

其實在學計算機方面我還是挺實用主義的,一直抱著碰到了再去仔細研究好了的態度,所以看書普遍不認真,只是求到時候能夠找得到參考。不過這本書我覺得格外有趣,所以也看得格外認真,把每節後的習題都做了,家庭作業則等著過兩天覆習(計劃是這樣的……)的時候加深印象。
不過一直沒找到csapp的實習手冊。其中有個“二進位制炸彈”實驗非常吸引人,典型的反彙編作業,有點點實現我小時候破解願望的感覺——希望找到以後不要讓我太失望,呵呵。

不過這本書還是有些不足之處。讓人感到最大的遺憾是最後三章“系統級I/O”“網路程式設計”“併發程式設計”講得比較簡略——自己正好是在這方面稍微熟悉點,覺得少了很多東西,有點遺憾。不過“併發程式設計”教給我了一個以前我根本不知道的東西——進度圖,用來解釋為什麼會出現死鎖以及如何解決實在是好極了(自己也是太孤陋寡聞……)。
另外還有個仔細讀了apue2以後還讓我非常困惑以至於還得上網查才弄明白的一件事,csapp當頭一句話就解決了,那就是csapp寫到pthread_detach函式時,說“為了避免儲存器洩露,每個可結合的執行緒都應該要麼被其他執行緒顯式地回收,要麼通過呼叫pthread_detach函式被分離”。而apue2關於detach的那段話硬是讓我雲裡霧裡,僅僅解釋了thread的行為和怎麼用,不講為什麼,害得我還得去查……不過apue2的thread部分不是W.Richard Stevens寫的,是Rago後加的,的確有質量差別……

想來書也是有輕重之分,csapp的重點還是再講硬體和軟體的結合部,後面系統偏應用級的東西只是做拋磚引玉之用,也是難怪。儘管是這樣,csapp有時還是會讓人眼前一亮。
這本書另外的問題就是雖然中文翻譯還算不錯——也是過了個修訂版的緣故,但是排版經常出錯,尤其是排彙編程式碼和註釋的時候。而且這個書名翻譯得特別沒勁,愣像是混雜在一堆國產計算機結構書裡的東西……
不過還是那句,瑕不掩瑜,csapp的確是我看過的最好的計算機書之一了(本來想不加之一的,不過不加至少有點對不起apue^_^)。

說回來,csapp的致謝裡面有這樣一句話:

最後,我們衷心感謝偉大的技術作家Brian Kernigam以及後來的W.Richard Stevens,他們向我們證明了技術書籍也能寫得如此優美。