第1章  如何使用本書 1
         1.1  路綫圖 1
         1.2  小問題 2
         1.3 除本書之外的選擇 3
         1.4  示例源代碼 4
         1.5  這本書屬於誰 4
         第2章  簡介 6
         2.1  導緻並行編程睏難的曆史原因 6
         2.2  並行編程的目標 7
         2.2.1  性能 8
         2.2.2  生産率 9
         2.2.3  通用性 9
         2.3  並行編程的替代方案 11
         2.3.1  串行應用的多個實例 11
         2.3.2  使用現有的並行軟件 11
         2.3.3  性能優化 12
         2.4  是什麼使並行編程變得復雜 12
         2.4.1  分割任務 13
         2.4.2  並行訪問控製 13
         2.4.3  資源分割和復製 14
         2.4.4  與硬件的交互 14
         2.4.5  組閤使用 14
         2.4.6  語言和環境如何支持這些任務 14
         2.5  本章的討論 15
         第3章  硬件和它的習慣 16
         3.1  概述 16
         3.1.1  流水綫CPU 16
         3.1.2  內存引用 17
         3.1.3  原子操作 18
         3.1.4  內存屏障 19
         3.1.5  高速緩存未命中 19
         3.1.6  I/O操作 19
         3.2  開銷 20
         3.2.1  硬件體係結構 20
         3.2.2  操作的開銷 21
         3.3  硬件的免費午餐 23
         3.3.1  3D集成 23
         3.3.2  新材料和新工藝 24
         3.3.3  是光,不是電子 24
         3.3.4  專用加速器 24
         3.3.5  現有的並行軟件 25
         3.4  對軟件設計的啓示 25
         第4章  辦事的傢夥 27
         4.1  腳本語言 27
         4.2  POSIX多進程 28
         4.2.1  POSIX進程創建和銷毀 28
         4.2.2  POSIX綫程創建和銷毀 30
         4.2.3  POSIX鎖 31
         4.2.4  POSIX讀/寫鎖 34
         4.3  原子操作 37
         4.4  Linux內核中類似POSIX的操作 38
         4.5  如何選擇趁手的工具 39
         第5章  計數 40
         5.1  為什麼並發計數不可小看 41
         5.2  統計計數器 42
         5.2.1  設計 43
         5.2.2  基於數組的實現 43
         5.2.3  最終結果一緻的實現 44
         5.2.4  基於每綫程變量的實現 46
         5.2.5  本節討論 48
         5.3  近似上限計數器 48
         5.3.1  設計 48
         5.3.2  簡單的上限計數實現 50
         5.3.3  關於簡單上限計數的討論 55
         5.3.4  近似上限計數器的實現 55
         5.3.5  關於近似上限計數器的討論 55
         5.4  精確上限計數 56
         5.4.1  原子上限計數的實現 56
         5.4.2  關於原子上限計數的討論 62
         5.4.3  Signal-Theft上限計數的設計 62
         5.4.4  Signal-Theft上限計數的實現 63
         5.4.5  關於Signal-Theft上限計數的討論 68
         5.5  特殊場閤的並行計數 68
         5.6  關於並行計數的討論 69
         5.6.1  並行計數的性能 70
         5.6.2  並行計數的專門化 71
         5.6.3  從並行計數中學到什麼 71
         第6章  對分割和同步的設計 73
         6.1  分割練習 73
         6.1.1  哲學傢就餐問題 73
         6.1.2  雙端隊列 75
         6.1.3  關於分割問題示例的討論 81
         6.2  設計準則 82
         6.3  同步粒度 83
         6.3.1  串行程序 84
         6.3.2  代碼鎖 85
         6.3.3  數據鎖 86
         6.3.4  數據所有權 88
         6.3.5  鎖粒度與性能 88
         6.4  並行快速路徑 90
         6.4.1  讀/寫鎖 91
         6.4.2  層次鎖 91
         6.4.3  資源分配器緩存 92
         6.5  分割之外 97
         6.5.1  使用工作隊列的迷宮問題並行解法 97
         6.5.2  另一種迷宮問題的並行解法 100
         6.5.3  性能比較I 102
         6.5.4  另一種迷宮問題的串行解法 104
         6.5.5  性能比較II 104
         6.5.6  未來展望與本節總結 105
         6.6  分割、並行化與優化 106
         第7章  鎖 107
         7.1  努力活著 108
         7.1.1  死鎖 108
         7.1.2  活鎖與飢餓 114
         7.1.3  不公平的鎖 116
         7.1.4  低效率的鎖 117
         7.2  鎖的類型 117
         7.2.1  互斥鎖 117
         7.2.2  讀/寫鎖 118
         7.2.3  讀/寫鎖之外 118
         7.2.4  範圍鎖 119
         7.3  鎖在實現中的問題 121
         7.3.1  基於原子交換的互斥鎖實現示例 121
         7.3.2  互斥鎖的其他實現 122
         7.4  基於鎖的存在保證 124
         7.5  鎖:是英雄還是惡棍 125
         7.5.1  應用程序中的鎖:英雄 125
         7.5.2  並行庫中的鎖:隻是一個工具 126
         7.5.3  並行化串行庫時的鎖:惡棍 128
         7.6  總結 130
         第8章  數據所有權 131
         8.1  多進程 131
         8.2  部分數據所有權和pthread綫程庫 132
         8.3  函數輸送 132
         8.4  指派綫程 132
         8.5  私有化 133
         8.6  數據所有權的其他用途 133
         第9章  延後處理 134
         9.1  引用計數 134
         9.1.1  各種引用計數的實現 135
         9.1.2  危險指針 140
         9.1.3  支持引用計數的Linux原語 141
         9.1.4  計數優化 142
         9.2  順序鎖 142
         9.3  讀-復製-修改(RCU) 145
         9.3.1  RCU介紹 145
         9.3.2  RCU基礎 147
         9.3.3  RCU用法 155
         9.3.4  Linux內核中的RCU API 166
         9.3.5  “玩具式”的RCU實現 171
         9.3.6  RCU練習 188
         9.4  如何選擇? 188
         9.5  更新端怎麼辦 190
         第10章  數據結構 191
         10.1  從例子入手 191
         10.2  可分割的數據結構 192
         10.2.1  哈希錶的設計 192
         10.2.2  哈希錶的實現 192
         10.2.3  哈希錶的性能 195
         10.3  讀側重的數據結構 197
         10.3.1  受RCU保護的哈希錶的實現 197
         10.3.2  受RCU保護的哈希錶的性能 199
         10.3.3  對受RCU保護的哈希錶的討論 201
         10.4  不可分割的數據結構 201
         10.4.1  可擴展哈希錶的設計 202
         10.4.2  可擴展哈希錶的實現 203
         10.4.3  可擴展哈希錶的討論 210
         10.4.4  其他可擴展的哈希錶 211
         10.5  其他數據結構 214
         10.6  微優化 214
         10.6.1  實例化 215
         10.6.2  比特與字節 215
         10.6.3  硬件層麵的考慮 216
         10.7  總結 217
         第11章  驗證 218
         11.1  簡介 218
         11.1.1  BUG來自於何處 218
         11.1.2  所需的心態 220
         11.1.3  應該何時開始驗證 221
         11.1.4  開源之路 221
         11.2  跟蹤 222
         11.3  斷言 223
         11.4  靜態分析 224
         11.5  代碼走查 224
         11.5.1  審查 224
         11.5.2  走查 225
         11.5.3  自查 225
         11.6  幾率及海森堡BUG 227
         11.6.1  離散測試統計 228
         11.6.2  濫用離散測試統計 229
         11.6.3  持續測試統計 229
         11.6.4  定位海森堡BUG 232
         11.7  性能評估 235
         11.7.1  性能基準 236
         11.7.2  剖析 236
         11.7.3  差分分析 237
         11.7.4  微基準 237
         11.7.5  隔離 237
         11.7.6  檢測乾擾 238
         11.8  總結 242
         第12章  形式驗證 244
         12.1  通用目的的狀態空間搜索 244
         12.1.1  Promela和Spin 244
         12.1.2  如何使用 Promela 249
         12.1.3  Promela 示例: 鎖 251
         12.1.4  Promela 示例: QRCU 254
         12.1.5  Promela初試牛刀:dynticks和可搶占RCU 260
         12.1.6  驗證可搶占RCU和dynticks 264
         12.2  特定目的的狀態空間搜索 288
         12.2.1  解析Litmus測試 289
         12.2.2  Litmus測試意味著什麼 290
         12.2.3  運行Litmus測試 291
         12.2.4  PPCMEM討論 292
         12.3  公理方法 293
         12.4  SAT求解器 294
         12.5  總結 295
         第13章  綜閤應用 296
         13.1  計數難題 296
         13.1.1  對更新進行計數 296
         13.1.2  對查找進行計數 296
         13.2  使用RCU拯救並行軟件性能 297
         13.2.1  RCU和基於每CPU變量的統計計數 297
         13.2.2  RCU及可插拔I/O設備的計數器 300
         13.2.3  數組及長度 300
         13.2.4  相關聯的字段 301
         13.3  散列難題 302
         13.3.1  相關聯的數據元素 302
         13.3.2  更新友好的哈希錶遍曆 303
         第14章  高級同步 304
         14.1  避免鎖 304
         14.2  內存屏障 304
         14.2.1  內存序及內存屏障 305
         14.2.2  如果B在A後麵,並且C在B後麵,為什麼C不在A後麵 306
         14.2.3  變量可以擁有多個值 307
         14.2.4  能信任什麼東西 308
         14.2.5  鎖實現迴顧 312
         14.2.6  一些簡單的規則 313
         14.2.7  抽象內存訪問模型 314
         14.2.8  設備操作 315
         14.2.9  保證 315
         14.2.10  什麼是內存屏障 316
         14.2.11  鎖約束 325
         14.2.12  內存屏障示例 326
         14.2.13  CPU緩存的影響 328
         14.2.14  哪裏需要內存屏障 329
         14.3  非阻塞同步 329
         14.3.1  簡單NBS 330
         14.3.2  NBS討論 331
         第15章  並行實時計算 332
         15.1  什麼是實時計算 332
         15.1.1  軟實時 332
         15.1.2  硬實時 333
         15.1.3  現實世界的實時 334
         15.2  誰需要實時計算 336
         15.3  誰需要並行實時計算 337
         15.4  實現並行實時係統 337
         15.4.1  實現並行實時操作係統 339
         15.4.2  實現並行實時應用 349
         15.5  實時VS.快速:如何選擇 351
         第16章  易於使用 353
         16.1  簡單是什麼 353
         16.2  API設計的Rusty準則 353
         16.3  修整Mandelbrot集閤 354
         第17章  未來的衝突 357
         17.1  曾經的CPU技術不代錶未來 357
         17.1.1  單處理器Uber Alles 358
         17.1.2  多綫程Mania 359
         17.1.3  更多類似的場景 359
         17.1.4  撞上內存牆 359
         17.2  事務內存 360
         17.2.1  外部世界 361
         17.2.2  進程修改 364
         17.2.3  同步 367
         17.2.4  討論 370
         17.3  硬件事務內存 371
         17.3.1  HTM與鎖相比的優勢 372
         17.3.2  HTM與鎖相比的劣勢 373
         17.3.3  HTM與增強後的鎖機製相比的劣勢 379
         17.3.4  HTM最適閤的場閤 380
         17.3.5  潛在的攪局者 380
         17.3.6  結論 382
         17.4  並行函數式編程 383
         附錄A  重要問題 385
         A.1 “After”的含義是什麼 385
         A.2 “並發”和“並行”之間的差異是什麼 388
         A.3  現在是什麼時間 389
         附錄B  同步原語 391
         B.1  組織和初始化 391
         B.1.1  smp_init() 391
         B.2  綫程創建、銷毀及控製 392
         B.2.1  create_thread() 392
         B.2.2  smp_thread_id() 392
         B.2.3  for_each_thread() 392
         B.2.4  for_each_running_thread() 392
         B.2.5  wait_thread() 393
         B.2.6  wait_all_threads() 393
         B.2.7  用法示例 393
         B.3  鎖 394
         B.3.1  spin_lock_init() 394
         B.3.2  spin_lock() 394
         B.3.3  spin_trylock() 394
         B.3.4  spin_unlock() 394
         B.3.5  用法示例 395
         B.4  每綫程變量 395
         B.4.1  DEFINE_PER_THREAD() 395
         B.4.2  DECLARE_PER_THREAD() 395
         B.4.3  per_thread() 395
         B.4.4  __get_thread_var() 396
         B.4.5  init_per_thread() 396
         B.4.6  用法示例 396
         B.5  性能 396
         附錄C  為什麼需要內存屏障 397
         C.1  緩存結構 397
         C.2  緩存一緻性協議 399
         C.2.1  MESI狀態 399
         C.2.2  MESI協議消息 400
         C.2.3  MESI狀態圖 400
         C.2.4  MESI協議示例 401
         C.3  存儲導緻不必要的停頓 402
         C.3.1  存儲緩衝 403
         C.3.2  存儲轉發 403
         C.3.3  存儲緩衝區及內存屏障 404
         C.4  存儲序列導緻不必要的停頓 406
         C.4.1  使無效隊列 406
         C.4.2  使無效隊列及使無效應答 407
         C.4.3  使無效隊列及內存屏障 407
         C.5  讀和寫內存屏障 409
         C.6  內存屏障示例 410
         C.6.1  亂序體係結構 410
         C.6.2  示例1 411
         C.6.3  示例2 412
         C.6.4  示例3 412
         C.7  特定的內存屏障指令 413
         C.7.1  Alpha 414
         C.7.2  AMD64 417
         C.7.3  ARMv7-A/R 417
         C.7.4  IA64 418
         C.7.5  PA-RISC 418
         C.7.6  POWER / Power PC 418
         C.7.7  SPARC RMO、PSO及TSO 419
         C.7.8  x86 420
         C.7.9  zSeries 421
         C.8  內存屏障是永恒的嗎 421
         C.9  對硬件設計者的建議 422
         附錄D  問題答案 423
         D.1  如何使用本書 423
         D.2  簡介 424
         D.3  硬件和它的習慣 427
         D.4  辦事的傢夥 429
         D.5  計數 433
         D.6  對分割和同步的設計 445
         D.7  鎖 449
         D.8  數據所有權 455
         D.9  延遲處理 456
         D.10  數據結構 471
         D.11  驗證 473
         D.12  形式驗證 478
         D.13  綜閤應用 481
         D.14  高級同步 483
         D.15  並行實時計算 486
         D.16  易於使用 487
         D.17  未來的衝突 487
         D.18  重要問題 490
         D.19  同步原語 491
         D.20  為什麼需要內存屏障 491
         附錄E  術語 495
         附錄F  感謝 502
         F.1  評審者 502
         F.2  硬件提供者 502
         F.3  原始齣處 503
         F.4  圖錶作者 503
         F.5  其他幫助 505
      · · · · · ·     (
收起)