1. 程式人生 > >《深入理解計算機系統(原書第三版)》pdf

《深入理解計算機系統(原書第三版)》pdf

目錄 · · · · · · 出版者的話 中文版序一 中文版序二 譯者序 前言 關於作者 第1章 計算機系統漫遊1 1.1 資訊就是位+上下文1 1.2 程式被其他程式翻譯成不同的格式3 1.3 瞭解編譯系統如何工作是大有益處的4 1.4 處理器讀並解釋儲存在記憶體中的指令5 1.4.1 系統的硬體組成5 1.4.2 執行hello程式7 1.5 快取記憶體至關重要9 1.6 儲存裝置形成層次結構9 1.7 作業系統管理硬體10 1.7.1 程序11 1.7.2 執行緒12 1.7.3 虛擬記憶體12 1.7.4 檔案14 1.8 系統之間利用網路通訊14 1.9 重要主題16 1.9.1 Amdahl定律16 1.9.2 併發和並行17 1.9.3 計算機系統中抽象的重要性19 1.10 小結20 參考文獻說明20 練習題答案20 第一部分 程式結構和執行 第2章 資訊的表示和處理22 2.1 資訊儲存24 2.1.1 十六進位制表示法25 2.1.2 字資料大小27 2.1.3 定址和位元組順序29 2.1.4 表示字串34 2.1.5 表示程式碼34 2.1.6 布林代數簡介35 2.1.7 C語言中的位級運算37 2.1.8 C語言中的邏輯運算39 2.1.9 C語言中的移位運算40 2.2 整數表示41 2.2.1 整型資料型別42 2.2.2 無符號數的編碼43 2.2.3 補碼編碼44 2.2.4 有符號數和無符號數之間的轉換49 2.2.5 C語言中的有符號數與無符號數52 2.2.6 擴充套件一個數字的位表示54 2.2.7 截斷數字56 2.2.8 關於有符號數與無符號數的建議58 2.3 整數運算60 2.3.1 無符號加法60 2.3.2 補碼加法62 2.3.3 補碼的非66 2.3.4 無符號乘法67 2.3.5 補碼乘法67 2.3.6 乘以常數70 2.3.7 除以2的冪71 2.3.8 關於整數運算的最後思考74 2.4 浮點數75 2.4.1 二進位制小數76 2.4.2 IEEE浮點表示78 2.4.3 數字示例79 2.4.4 舍入83 2.4.5 浮點運算85 2.4.6 C語言中的浮點數86 2.5 小結87 參考文獻說明88 家庭作業88 練習題答案97 第3章 程式的機器級表示109 3.1 歷史觀點110 3.2 程式編碼113 3.2.1 機器級程式碼113 3.2.2 程式碼示例114 3.2.3 關於格式的註解117 3.3 資料格式119 3.4 訪問資訊119 3.4.1 運算元指示符121 3.4.2 資料傳送指令122 3.4.3 資料傳送示例125 3.4.4 壓入和彈出棧資料127 3.5 算術和邏輯操作128 3.5.1 載入有效地址129 3.5.2 一元和二元操作130 3.5.3 移位操作131 3.5.4 討論131 3.5.5 特殊的算術操作133 3.6 控制135 3.6.1 條件碼135 3.6.2 訪問條件碼136 3.6.3 跳轉指令138 3.6.4 跳轉指令的編碼139 3.6.5 用條件控制來實現條件分支…141 3.6.6 用條件傳送來實現條件分支…145 3.6.7 迴圈149 3.6.8 switch語句159 3.7 過程164 3.7.1 執行時棧164 3.7.2 轉移控制165 3.7.3 資料傳送168 3.7.4 棧上的區域性儲存170 3.7.5 暫存器中的區域性儲存空間172 3.7.6 遞迴過程174 3.8 陣列分配和訪問176 3.8.1 基本原則176 3.8.2 指標運算177 3.8.3 巢狀的陣列178 3.8.4 定長陣列179 3.8.5 變長陣列181 3.9 異質的資料結構183 3.9.1 結構183 3.9.2 聯合186 3.9.3 資料對齊189 3.10 在機器級程式中將控制與資料結合起來192 3.10.1 理解指標192 3.10.2 應用:使用GDB偵錯程式193 3.10.3 記憶體越界引用和緩衝區溢位194 3.10.4 對抗緩衝區溢位攻擊198 3.10.5 支援變長棧幀201 3.11 浮點程式碼204 3.11.1 浮點傳送和轉換操作205 3.11.2 過程中的浮點程式碼209 3.11.3 浮點運算操作210 3.11.4 定義和使用浮點常數212 3.11.5 在浮點程式碼中使用位級操作212 3.11.6 浮點比較操作213 3.11.7 對浮點程式碼的觀察結論215 3.12 小結216 參考文獻說明216 家庭作業216 練習題答案226 第4章 處理器體系結構243 4.1 Y86-64指令集體系結構245 4.1.1 程式設計師可見的狀態245 4.1.2 Y86-64指令245 4.1.3 指令編碼246 4.1.4 Y86-64異常250 4.1.5 Y86-64程式251 4.1.6 一些Y86-64指令的詳情255 4.2 邏輯設計和硬體控制語言HCL256 4.2.1 邏輯閘257 4.2.2 組合電路和HCL布林表示式257 4.2.3 字級的組合電路和HCL整數表示式258 4.2.4 集合關係261 4.2.5 儲存器和時鐘262 4.3 Y86-64的順序實現264 4.3.1 將處理組織成階段264 4.3.2 SEQ硬體結構272 4.3.3 SEQ的時序274 4.3.4 SEQ階段的實現277 4.4 流水線的通用原理282 4.4.1 計算流水線282 4.4.2 流水線操作的詳細說明284 4.4.3 流水線的侷限性284 4.4.4 帶反饋的流水線系統287 4.5 Y86-64的流水線實現288 4.5.1 SEQ+:重新安排計算階段288 4.5.2 插入流水線暫存器289 4.5.3 對訊號進行重新排列和標號292 4.5.4 預測下一個PC293 4.5.5 流水線冒險295 4.5.6 異常處理306 4.5.7 PIPE各階段的實現308 4.5.8 流水線控制邏輯314 4.5.9 效能分析322 4.5.10 未完成的工作323 4.6 小結325 參考文獻說明326 家庭作業327 練習題答案331 第5章 優化程式效能341 5.1 優化編譯器的能力和侷限性342 5.2 表示程式效能345 5.3 程式示例347 5.4 消除迴圈的低效率350 5.5 減少過程呼叫353 5.6 消除不必要的記憶體引用354 5.7 理解現代處理器357 5.7.1 整體操作357 5.7.2 功能單元的效能361 5.7.3 處理器操作的抽象模型362 5.8 迴圈展開366 5.9 提高並行性369 5.9.1 多個累積變數370 5.9.2 重新結合變換373 5.10 優化合並程式碼的結果小結377 5.11 一些限制因素378 5.11.1 暫存器溢位378 5.11.2 分支預測和預測錯誤處罰379 5.12 理解記憶體效能382 5.12.1 載入的效能382 5.12.2 儲存的效能383 5.13 應用:效能提高技術387 5.14 確認和消除效能瓶頸388 5.14.1 程式剖析388 5.14.2 使用剖析程式來指導優化390 5.15 小結392 參考文獻說明393 家庭作業393 練習題答案395 第6章 儲存器層次結構399 6.1 儲存技術399 6.1.1 隨機訪問儲存器400 6.1.2 磁碟儲存406 6.1.3 固態硬碟414 6.1.4 儲存技術趨勢415 6.2 區域性性418 6.2.1 對程式資料引用的區域性性418 6.2.2 取指令的區域性性419 6.2.3 區域性性小結420 6.3 儲存器層次結構421 6.3.1 儲存器層次結構中的快取422 6.3.2 儲存器層次結構概念小結424 6.4 快取記憶體儲存器425 6.4.1 通用的快取記憶體儲存器組織結構425 6.4.2 直接對映快取記憶體427 6.4.3 組相聯快取記憶體433 6.4.4 全相聯快取記憶體434 6.4.5 有關寫的問題437 6.4.6 一個真實的快取記憶體層次結構的解剖438 6.4.7 快取記憶體引數的效能影響439 6.5 編寫快取記憶體友好的程式碼440 6.6 綜合:快取記憶體對程式效能的影響444 6.6.1 儲存器山444 6.6.2 重新排列迴圈以提高空間區域性性447 6.6.3 在程式中利用區域性性450 6.7 小結450 參考文獻說明451 家庭作業451 練習題答案459 第二部分 在系統上執行程式 第7章 連結464 7.1 編譯器驅動程式465 7.2 靜態連結466 7.3 目標檔案466 7.4 可重定位目標檔案467 7.5 符號和符號表468 7.6 符號解析470 7.6.1 連結器如何解析多重定義的全域性符號471 7.6.2 與靜態庫連結475 7.6.3 連結器如何使用靜態庫來解析引用477 7.7 重定位478 7.7.1 重定位條目479 7.7.2 重定位符號引用479 7.8 可執行目標檔案483 7.9 載入可執行目標檔案484 7.10 動態連結共享庫485 7.11 從應用程式中載入和連結共享庫487 7.12 位置無關程式碼489 7.13 庫打樁機制492 7.13.1 編譯時打樁492 7.13.2 連結時打樁492 7.13.3 執行時打樁494 7.14 處理目標檔案的工具496 7.15 小結496 參考文獻說明497 家庭作業497 練習題答案499 第8章 異常控制流501 8.1 異常502 8.1.1 異常處理503 8.1.2 異常的類別504 8.1.3 Linux/x86-64系統中的異常505 8.2 程序508 8.2.1 邏輯控制流508 8.2.2 併發流509 8.2.3 私有地址空間509 8.2.4 使用者模式和核心模式510 8.2.5 上下文切換511 8.3 系統呼叫錯誤處理512 8.4 程序控制513 8.4.1 獲取程序ID513 8.4.2 建立和終止程序513 8.4.3 回收子程序516 8.4.4 讓程序休眠521 8.4.5 載入並執行程式521 8.4.6 利用fork和execve執行程式524 8.5 訊號526 8.5.1 訊號術語527 8.5.2 傳送訊號528 8.5.3 接收訊號531 8.5.4 阻塞和解除阻塞訊號532 8.5.5 編寫訊號處理程式533 8.5.6 同步流以避免討厭的併發錯誤540 8.5.7 顯式地等待訊號543 8.6 非本地跳轉546 8.7 操作程序的工具550 8.8 小結550 參考文獻說明550 家庭作業550 練習題答案556 第9章 虛擬記憶體559 9.1 物理和虛擬定址560 9.2 地址空間560 9.3 虛擬記憶體作為快取的工具561 9.3.1 DRAM快取的組織結構562 9.3.2 頁表562 9.3.3 頁命中563 9.3.4 缺頁564 9.3.5 分配頁面565 9.3.6 又是區域性性救了我們565 9.4 虛擬記憶體作為記憶體管理的工具565 9.5 虛擬記憶體作為記憶體保護的工具567 9.6 地址翻譯567 9.6.1 結合快取記憶體和虛擬記憶體570 9.6.2 利用TLB加速地址翻譯570 9.6.3 多級頁表571 9.6.4 綜合:端到端的地址翻譯573 9.7 案例研究:Intel Core i7/Linux記憶體系統576 9.7.1 Core i7地址翻譯576 9.7.2 Linux虛擬記憶體系統580 9.8 記憶體對映582 9.8.1 再看共享物件583 9.8.2 再看fork函式584 9.8.3 再看execve函式584 9.8.4 使用mmap函式的使用者級記憶體對映585 9.9 動態記憶體分配587 9.9.1 malloc和free函式587 9.9.2 為什麼要使用動態記憶體分配589 9.9.3 分配器的要求和目標590 9.9.4 碎片591 9.9.5 實現問題592 9.9.6 隱式空閒連結串列592 9.9.7 放置已分配的塊593 9.9.8 分割空閒塊594 9.9.9 獲取額外的堆記憶體594 9.9.10 合併空閒塊594 9.9.11 帶邊界標記的合併595 9.9.12 綜合:實現一個簡單的分配器597 9.9.13 顯式空閒連結串列603 9.9.14 分離的空閒連結串列604 9.10 垃圾收集605 9.10.1 垃圾收集器的基本知識606 9.10.2 Mark&Sweep垃圾收集器607 9.10.3 C程式的保守Mark&Sweep608 9.11 C程式中常見的與記憶體有關的錯誤609 9.11.1 間接引用壞指標609 9.11.2 讀未初始化的記憶體609 9.11.3 允許棧緩衝區溢位610 9.11.4 假設指標和它們指向的物件是相同大小的610 9.11.5 造成錯位錯誤611 9.11.6 引用指標,而不是它所指向的物件611 9.11.7 誤解指標運算611 9.11.8 引用不存在的變數612 9.11.9 引用空閒堆塊中的資料612 9.11.10 引起記憶體洩漏613 9.12 小結613 參考文獻說明613 家庭作業614 練習題答案617 第三部分 程式間的互動和通訊 第10章 系統級I/O622 10.1 Unix I/O622 10.2 檔案623 10.3 開啟和關閉檔案624 10.4 讀和寫檔案625 10.5 用RIO包健壯地讀寫626 10.5.1 RIO的無緩衝的輸入輸出函式627 10.5.2 RIO的帶緩衝的輸入函式627 10.6 讀取檔案元資料632 10.7 讀取目錄內容633 10.8 共享檔案634 10.9 I/O重定向637 10.10 標準I/O638 10.11 綜合:我該使用哪些I/O函式?638 10.12 小結640 參考文獻說明640 家庭作業640 練習題答案641 第11章 網路程式設計642 11.1 客戶端伺服器程式設計模型642 11.2 網路643 11.3 全球IP因特網646 11.3.1 IP地址647 11.3.2 因特網域名649 11.3.3 因特網連線651 11.4 套接字介面652 11.4.1 套接字地址結構653 11.4.2 socket函式654 11.4.3 connect函式654 11.4.4 bind函式654 11.4.5 listen函式655 11.4.6 accept函式655 11.4.7 主機和服務的轉換656 11.4.8 套接字介面的輔助函式660 11.4.9 echo客戶端和伺服器的示例662 11.5 Web伺服器665 11.5.1 Web基礎665 11.5.2 Web內容666 11.5.3 HTTP事務667 11.5.4 服務動態內容669 11.6 綜合:TINY Web伺服器671 11.7 小結678 參考文獻說明678 家庭作業678 練習題答案679 第12章 併發程式設計681 12.1 基於程序的併發程式設計682 12.2 基於I/O多路複用的併發程式設計684 12.3 基於執行緒的併發程式設計691 12.4 多執行緒程式中的共享變數696 12.5 用訊號量同步執行緒698 12.6 使用執行緒提高並行性710 12.7 其他併發問題716 12.8 小結722 參考文獻說明723 家庭作業723 練習題答案726 附錄A 錯誤處理729