內容簡介
編寫可擴展的、快速、強大、節能的程式,才適合處理大量數據。使用並行編程,可將數據處理任務分布在多個CPU上完成,從而從根本上提高性能。只需要稍加學習,讀者就可以創建速度和效率的軟體。
《並行計算與高性能計算》將講述用於提高代碼運行效率的技術。你將學習評估硬體架構,學會使用OpenMP和MPI等行業標準工具,將掌握用於高性能計算的數據結構和算法,並學習手持設備的節能技術。你甚至可在一組GPU上運行大規模海嘯仿真程式。
主要內容
●規劃新的並行項目
●了解CPU和GPU架構上的差異
●找到性能不佳的核心和循環
●使用批處理調度來管理應用程式
圖書目錄
第Ⅰ部分 並行計算介紹
第1 章 為什麼使用並行計算 3
1.1 為什麼要學習並行計算 5
1.2 並行計算的基本定律 9
1.3 並行計算如何工作 12
1.4 對並行方法進行分類 24
1.5 並行策略 25
1.6 並行加速與比較加速:兩種不同的衡量標準 26
1.7 你將在本書中學到哪些內容 27
1.8 本章小結 28
第2 章 規劃並行化 29
2.1 處理新項目:準備工作 30
2.2 概要分析:探測系統功能和應用程式性能之間的差距 42
2.3 計畫:成功的基礎 42
2.4 實施 44
2.5 提交:高質量的打包過程 45
2.6 進一步探索 46
2.7 本章小結 46
第3 章 性能極限與分析 49
3.1 了解應用程式的潛在性能限制 49
3.2 了解硬體性能:基準測試 52
3.3 描述你的應用程式:分析 59
3.4 進一步探索 71
3.5 本章小結 71
第4 章 數據設計和性能模型 73
4.1 數據結構與性能:面向數據的設計 74
4.2 快取未命中的3C:強制、容量與衝突 86
4.3 簡單性能模型:案例研究 90
4.4 高級性能模型 98
4.5 網路訊息 101
4.6 進一步探索 103
4.7 本章小結 104
第5 章 並行算法與模式 105
5.1 並行計算套用的算法分析 105
5.2 性能模型與算法複雜性 106
5.3 什麼是並行算法 109
5.4 什麼是哈希函式 110
5.5 空間哈希:一種高並行度算法 111
5.6 prefix sum(掃描)模式及其在並行計算中的重要性 132
5.7 並行全局和:解決關聯性問題 135
5.8 並行算法研究的未來 141
5.9 進一步探索 141
5.10 本章小結 142
第II 部分 CPU:並行的主力第6 章 向量化:免費的flop 145
6.1 向量及單指令多數據流(SIMD)概要 145
6.2 向量化的硬體趨勢 146
6.3 向量化方法 147
6.4 實現更好向量化的編程風格 163
6.5 與編譯器向量化相關的編譯器標誌 164
6.6 使用OpenMP SIMD 指令實現更好的移植性 170
6.7 進一步探索 172
6.8 本章小結 173
第7 章 使用OpenMP 實現並行計算 175
7.1 OpenMP 介紹 175
7.2 典型的OpenMP 用例:循環級OpenMP、高級OpenMP 和MPI +OpenMP 183
7.3 標準循環級OpenMP 示例 185
7.4 OpenMP 中變數範圍對結果準確性的重要性 193
7.5 函式級OpenMP:使整個函式實現執行緒並行 194
7.6 使用高級OpenMP 改進並行可伸縮性 196
7.7 使用OpenMP 混合執行緒及向量化 201
7.8 使用OpenMP 的高級示例 204
7.9 執行緒工具對健壯程式的重要性 210
7.10 基於任務的支持算法示例 213
7.11 進一步探索 214
7.12 本章小結 215
第8 章 MPI:並行骨幹 217
8.1 MPI 程式基礎 217
8.2 用於進程間通信的傳送和接收命令 221
8.3 聚合通信:MPI 的強大組件 227
8.4 數據並行示例 236
8.5 使用高級MPI 功能來簡化代碼和啟用最佳化 245
8.6 通過聯合使用MPI 和OpenMP實現極高的可擴展性 257
8.7 進一步探索 259
8.8 本章小結 261
第III 部分 GPU:加速應用程式運行
第9 章 GPU 架構及概念 265
9.1 作為加速計算平台的CPU-GPU系統 266
9.2 GPU 和執行緒引擎 268
9.3 GPU 記憶體空間的特點 272
9.4 PCI 匯流排:CPU 與GPU 之間的數據傳輸橋樑 278
9.5 多GPU 平台和MPI 284
9.6 GPU 加速平台的潛在收益 286
9.7 何時使用GPU 292
9.8 進一步探索 292
9.9 本章小結 293
第10 章 GPU 編程模型 295
10.1 GPU 編程抽象:通用框架 296
10.2 GPU 編程模型的代碼結構 302
10.3 最佳化GPU 資源利用 306
10.4 約減模式需要跨工作組進行同步 309
10.5 通過佇列(流)進行異步計算 310
10.6 為GPU 定製並行化應用程式的策略 311
10.7 進一步探索 312
10.8 本章小結 314
第11 章 基於指令的GPU 編程 315
11.1 為GPU 實現套用編譯指令和pragma 的過程 316
11.2 OpenACC:在GPU 上運行的最簡單方法 317
11.2.1 編譯OpenACC 代碼 319
11.2.2 OpenACC 中用於加速計算的並行計算區域 320
11.2.3 使用指令減少CPU 和GPU之間的數據移動 325
11.2.4 最佳化GPU kernel 329
11.2.5 stream triad 性能結果的總結 334
11.2.6 高級OpenACC 技術 335
11.3 OpenMP:加速器領域的重量級選手 337
11.3.1 編譯OpenMP 代碼 337
11.3.2 使用OpenMP 在GPU 上生成並行工作 339
11.3.3 使用OpenMP 創建數據區域來控制到GPU 的數據移動 342
11.3.4 為GPU 最佳化OpenMP 346
11.3.5 用於GPU 的高級OpenMP 350
11.4 進一步探索 353
11.4.1 擴展閱讀 353
11.4.2 練習 354
11.5 本章小結 355
第12 章 GPU 語言:深入了解基礎知識 357
12.1 原生GPU 程式語言的特性 358
12.2 CUDA 和HIP GPU 語言:底層性能選項 359
12.2.1 編寫和構建第一個CUDA應用程式 360
12.2.2 CUDA 的約減kernel:事情變得複雜 367
12.2.3 Hipifying CUDA 代碼 372
12.3 OpenCL:用於可移植的開源GPU 語言 375
12.3.1 編寫和構建第一個OpenCL應用程式 376
12.3.2 OpenCL 中的約減 381
12.4 SYCL:一個成為主流的實驗性C++實現 384
12.5 性能可移植性的高級語言 387
12.5.1 Kokkos:性能可移植性生態系統 387
12.5.2 RAJA 提供更具適應性的性能可移植性層 390
12.6 進一步探索 392
12.6.1 擴展閱讀 392
12.6.2 練習 393
12.7 本章小結 393
第13 章 GPU 配置分析及工具 395
13.1 分析工具概要 395
13.2 如何選擇合適的工作流 396
13.3 問題示例:淺水仿真 397
13.4 分析工作流的示例 400
13.4.1 運行淺水應用程式 400
13.4.2 分析CPU 代碼來制定行動計畫 402
13.4.3 為實施步驟添加OpenACC計算指令 403
13.4.4 添加數據移動指令 405
13.4.5 通過引導分析獲取改進建議 406
13.4.6 強大的輔助開發工具:NVIDIA Nsight 工具套件 408
13.4.7 用於AMD GPU 生態系統的CodeXL 409
13.5 專注於重要指標 409
13.5.1 利用率:是否有足夠的工作量 410
13.5.2 發布效率:你的warp 是否經常停滯? 410
13.5.3 獲得頻寬 411
13.6 使用容器和虛擬機來提供備用工作流 411
13.6.1 將Docker 容器作為解決方案 411
13.6.2 使用VirtualBox 虛擬機 413
13.7 移入雲端:提供靈活和可擴展能力 415
13.8 進一步探索 415
13.8.1 擴展閱讀 415
13.8.2 練習 416
13.9 本章小結 416
第Ⅳ部分 高性能計算生態系統
第14 章 關聯性:與kernel 休戰 419
14.1 為什麼關聯性很重要 420
14.2 探索架構 421
14.3 OpenMP 的執行緒關聯 422
14.4 進程關聯性與MPI 429
14.4.1 OpenMPI 的默認進程放置 429
14.4.2 進行控制:在OpenMPI 中指定進程放置的基本技術 430
14.4.3 關聯性不僅僅是進程綁定:全面討論 434
14.5 MPI+OpenMP 的關聯性 436
14.6 從命令行控制關聯性 440
14.6.1 使用hwloc-bind 分配關聯性 440
14.6.2 使用likwid-pin: likwid 工具套件中的關聯工具 441
14.7 展望未來:在運行時設定和更改關聯性 443
14.7.1 在執行檔中設定關聯性 443
14.7.2 在運行時更改進程關聯性 445
14.8 進一步探索 447
14.8.1 擴展閱讀 447
14.8.2 練習 448
14.9 本章小結 449
第15 章 批處理調度器:為混亂帶來秩序 451
15.1 無管理系統所帶來的混亂 452
15.2 如何順利地在繁忙的集群中部署任務 452
15.2.1 繁忙集群中的批處理系統布局 453
15.2.2 如何合理地在繁忙的集群和HPC 站點上運行任務:HPC 中的推薦做法 453
15.3 提交第一個批處理腳本 454
15.4 為長時間運行的作業設定自動重啟 459
15.5 在批處理腳本中指定依賴項 463
15.6 進一步探索 465
15.6.1 擴展閱讀 465
15.6.2 練習 465
15.7 本章小結 466
第16 章 並行環境的檔案操作 467
16.1 高性能檔案系統的組成部分 467
16.2 標準檔案操作:並行到串列(parallel-to-serial)接口 468
16.3 在並行環境中使用MPI
檔案操作(MPI-IO) 469
16.4 HDF5 具有自我描述功能,可更好地管理數據 477
16.5 其他並行檔案軟體包 485
16.6 並行檔案系統:硬體接口 485
16.6.1 並行檔案設定 485
16.6.2 適用於所有檔案系統的通用提示 489
16.6.3 特定檔案系統的提示 490
16.7 進一步探索 493
16.7.1 擴展閱讀 493
16.7.2 練習 494
16.8 本章小結 494
第17 章 用於編寫優質代碼的工具和資源 495
17.1 版本控制系統:一切從這裡開始 497
17.1.1 分散式版本控制更適合全局協作 498
17.1.2 通過集中版本控制來簡化操作並提高代碼安全 498
17.2 用於跟蹤代碼性能的計時器例程 499
17.3 分析器:不去衡量就無法提升 500
17.3.1 日常使用的基於文本的分析器 501
17.3.2 用於快速識別瓶頸的高級分析器 502
17.3.3 使用中級分析器來指導應用程式開發 502
17.3.4 通過詳細分析器了解硬體性能的細節信息 504
17.4 benchmark 和mini-apps:了解系統性能的視窗 504
17.4.1 使用benchmark 測量系統性能特徵 504
17.4.2 通過mini-apps 提供應用程式的視角 505
17.5 為健壯的應用程式檢測及修復記憶體錯誤 507
17.5.1 valgrind Memcheck:備用開源方案 507
17.5.2 使用Dr. Memory 診斷記憶體問題 507
17.5.3 對於要求嚴苛的應用程式使用商業記憶體檢測工具 509
17.5.4 使用基於編譯器的記憶體工具來簡化操作 509
17.5.5 通過Fence-post 檢查器來檢測越界記憶體訪問 510
17.5.6 GPU 應用程式所使用的記憶體工具 511
17.6 用於檢測競態條件的執行緒檢查器 512
17.6.1 Intel Inspector:帶有GUI 的競態條件檢測工具 512
17.6.2 Archer:一個基於文本的檢測競態條件的工具 512
17.7 Bug-busters:用於消除bug 的調試器 514
17.7.1 在HPC 站點中廣泛使用的TotalView 調試器 514
17.7.2 DDT:另一種在HPC 站點廣泛使用的調試器 514
17.7.3 Linux 調試器:為本地開發需求提供免費的替代方案 515
17.7.4 通過GPU 調試器消除GPU bug 515
17.8 檔案操作分析 516
17.9 包管理器:你的個人系統管理員 519
17.9.1 macOS 的包管理器 519
17.9.2 Windows 包管理器 519
17.9.3 Spack 包管理器:用於高性能計算的包管理器 519
17.10 模組:載入專門的工具鏈 520
17.10.1 TCL modules:用於載入軟體工具鏈的原始模組系統 522
17.10.2 Lmod:基於Lua 的替代模組實現 523
17.11 思考與練習 523
17.12 本章小結 523
附錄A 參考資料 (可從配書網站下載)
附錄B 習題答案 (可從配書網站下載)