主要內(nèi)容 ●規(guī)劃新的并行項(xiàng)目 ●了解CPU和GPU架構(gòu)上的差異 ●找到性能不佳的內(nèi)核和循環(huán) ●使用批處理調(diào)度來管理應(yīng)用程序
編寫可擴(kuò)展的、快速、強(qiáng)大、節(jié)能的程序,才適合處理大量數(shù)據(jù)。使用并行編程,可將數(shù)據(jù)處理任務(wù)分布在多個(gè)CPU上完成,從而從根本上提高性能。只需要稍加學(xué)習(xí),讀者就可以創(chuàng)建速度和效率最大化的軟件。
《并行計(jì)算與高性能計(jì)算》將講述用于提高代碼運(yùn)行效率的技術(shù)。你將學(xué)習(xí)評(píng)估硬件架構(gòu),學(xué)會(huì)使用OpenMP和MPI等行業(yè)標(biāo)準(zhǔn)工具,將掌握用于高性能計(jì)算的數(shù)據(jù)結(jié)構(gòu)和算法,并學(xué)習(xí)手持設(shè)備的節(jié)能技術(shù)。你甚至可在一組GPU上運(yùn)行大規(guī)模海嘯仿真程序。
探險(xiǎn)家最重要的任務(wù)之一就是為后來者畫一張地圖。這對(duì)我們這些在科技領(lǐng)域不斷開拓的人來說尤其如此。我們?cè)诒緯械哪繕?biāo)是為那些剛剛開始學(xué)習(xí)并行和高性能計(jì)算的人以及那些想要擴(kuò)大知識(shí)面的人提供一個(gè)路線圖。高性能計(jì)算是一個(gè)快速變化的領(lǐng)域,其中的語言和技術(shù)一直在變化。
出于這個(gè)原因,我們將關(guān)注長期保持穩(wěn)定的基本面。對(duì)于用于CPU 和GPU 的計(jì)算機(jī)語言,我們強(qiáng)調(diào)跨許多語言的通用模式,以便你可以快速地為當(dāng)前任務(wù)選擇最合適的語言。
本書的目標(biāo)讀者
本書適用于本科階段高年級(jí)的并行計(jì)算課程,也可以作為從事計(jì)算工作的專業(yè)人員的最新文獻(xiàn)。如果你對(duì)性能感興趣,無論是運(yùn)行時(shí)間、規(guī)模還是處理能力,本書都將為你提供改進(jìn)應(yīng)用程序和超越競爭對(duì)手的工具。隨著處理器達(dá)到規(guī)模、熱量以及功率的極限,我們不能指望下一代計(jì)算機(jī)來加快運(yùn)行我們的應(yīng)用程序。越來越多的高技能和知識(shí)淵博的程序員對(duì)于從當(dāng)今的應(yīng)用程序中獲得最大性能至關(guān)重要。
在本書中,我們可以了解當(dāng)今高性能計(jì)算硬件的關(guān)鍵思想。這些是為了性能而編程的基本真理。
這些主題構(gòu)成了整本書的基礎(chǔ)。
在高性能計(jì)算中,關(guān)鍵不在于編寫代碼的速度有多快,而在于代碼運(yùn)行的有多快。
這一想法總結(jié)了為高性能計(jì)算編寫應(yīng)用程序意味著什么。對(duì)于大多數(shù)其他應(yīng)用程序,關(guān)注的重點(diǎn)是如何能夠快速地完成編寫應(yīng)用程序的過程。如今,計(jì)算機(jī)語言的設(shè)計(jì)通常是為了提高編程速度,而不是提高代碼的性能。雖然這種編程方法長期以來一直存在于高性能計(jì)算應(yīng)用程序,但它還沒有得到廣泛的記錄或描述。在第4 章中,我們將在最近被稱為面向數(shù)據(jù)設(shè)計(jì)的編程方法中討論這一點(diǎn)。
一切都與內(nèi)存有關(guān):將多少內(nèi)容加載到內(nèi)存以及加載的頻率。
即使你知道可用內(nèi)存和內(nèi)存操作幾乎總是性能的瓶頸,但我們依舊傾向于花大量時(shí)間考慮浮點(diǎn)操作。目前大多數(shù)計(jì)算硬件對(duì)于每個(gè)內(nèi)存負(fù)載能夠執(zhí)行50 個(gè)浮點(diǎn)操作,因此浮點(diǎn)操作已經(jīng)是次要的了。在幾乎每一章中,我們都使用了STREAM 基準(zhǔn)測試,這是一個(gè)內(nèi)存性能測試,用來驗(yàn)證我們是否從硬件和編程語言中獲得了合理的性能。
如果加載一個(gè)值,則得到8 或16。
這就像買雞蛋一樣。你不可能每次只買一個(gè)。內(nèi)存負(fù)載由512 位的高速緩存行完成。對(duì)于8 字節(jié)的雙精度值,無論是否需要,都將加載8 個(gè)值。所以在編程過程中,讓你的程序一次使用多個(gè)值而不是一個(gè)值,而且最好是使用8 個(gè)連續(xù)的值,這樣可以獲得最佳性能。如果代碼中存在任何缺陷,并行執(zhí)行時(shí)將暴露它們。
與串行運(yùn)行的應(yīng)用程序相比,在高性能計(jì)算中需要更多地關(guān)注代碼質(zhì)量。代碼質(zhì)量將貫穿整個(gè)并行化生命周期。使用并行化,你更有可能在程序中觸發(fā)缺陷,而且還會(huì)發(fā)現(xiàn)調(diào)試并行程序更具挑戰(zhàn)性,特別是在大規(guī)模使用并行的情況下。我們將在第2 章中介紹提高編程質(zhì)量的方法,并在整個(gè)章節(jié)中都一直使用可以提高編程質(zhì)量的工具,最后,在第17 章中,我們列出了其他優(yōu)秀的用于提高編程質(zhì)量的工具。
這些關(guān)鍵主題不局限于硬件類型,對(duì)于CPU 環(huán)境和GPU 環(huán)境都同樣適用。同時(shí)支持CPU 與GPU 是因?yàn)樵诂F(xiàn)實(shí)中運(yùn)行高性能程序往往受到物理硬件的限制,不可能所有的硬件都有GPU 環(huán)境。
本書內(nèi)容的基本路線圖
這本書并不要求你具備任何并行編程的知識(shí),但希望你最好是一位熟練的程序員,并且熟悉高性能編譯語言,如C、C 或Fortran;同時(shí)也希望你對(duì)計(jì)算術(shù)語、操作系統(tǒng)基礎(chǔ)知識(shí)和網(wǎng)絡(luò)有一定的了解,并且能夠完成其他的計(jì)算機(jī)操作,比如安裝軟件和完成輕量化的系統(tǒng)任務(wù)管理。
計(jì)算硬件的知識(shí)或許是對(duì)讀者最重要的要求。我們建議打開計(jì)算機(jī),查看每個(gè)組件,并了解其物理特性。
本書由組成高性能世界的以下四部分組成。
● 第Ⅰ部分:并行計(jì)算介紹(第1~5 章)
● 第Ⅱ部分:CPU:并行的主力(第6~8 章)
● 第Ⅲ部分:GPU:加速應(yīng)用程序運(yùn)行(第9~13 章)
● 第Ⅳ部分:高性能計(jì)算生態(tài)系統(tǒng)(第14~17 章)
本書設(shè)計(jì)的主體順序是面向處理高性能計(jì)算項(xiàng)目的人員。例如,對(duì)于應(yīng)用程序項(xiàng)目,在項(xiàng)目開始之前,了解第2 章中介紹的軟件工程主題是必要的。一旦軟件工程就位,接下來就要決定數(shù)據(jù)結(jié)構(gòu)和算法。然后是使用CPU 或GPU 進(jìn)行實(shí)現(xiàn)。最后,為應(yīng)用程序使用并行文件系統(tǒng)或高性能計(jì)算系統(tǒng)的其他特有特性。
另一方面,我們的一些讀者對(duì)獲得并行編程的基本技能更感興趣,可能想直接進(jìn)入MPI 或
OpenMP 章節(jié)。今天,并行計(jì)算的技術(shù)如此豐富,所以不要止步于此。比如從可以將應(yīng)用程序的速度提高一個(gè)數(shù)量級(jí)的GPU,到可以提高代碼質(zhì)量或指出需要優(yōu)化的代碼段的工具潛在的收益僅受你的時(shí)間和專業(yè)知識(shí)的限制。
如果你將本書作為并行計(jì)算課程的教材,那么本書所提供的內(nèi)容足夠支撐兩個(gè)學(xué)期的時(shí)間。你可將本書當(dāng)作并行與高性能計(jì)算的知識(shí)集合,可根據(jù)自己的情況來選擇學(xué)習(xí)的主題,并制定課程目標(biāo),比如下面列出的自定義學(xué)習(xí)目標(biāo)的例子:
● 第1 章提供了并行計(jì)算的介紹。
● 第3 章講解測量硬件和應(yīng)用程序性能的方法。
● 第4.1~4.2 節(jié)描述面向數(shù)據(jù)的編程設(shè)計(jì)概念、多維數(shù)組和緩存基礎(chǔ)知識(shí)。
● 第7 章討論OpenMP(Open Multi-Processing)以獲得節(jié)點(diǎn)上的并行性。
● 第8 章介紹消息傳遞接口(Message Passing Interface,MPI),用于實(shí)現(xiàn)跨多個(gè)節(jié)點(diǎn)的分布式并行。
● 第14.1~14.5 節(jié)介紹關(guān)聯(lián)性與流程布局的概念。
● 第9 章和第10 章描述了GPU 硬件和編程模型。
● 第11.1~11.2 節(jié)主要介紹如何使用OpenACC 讓應(yīng)用程序在GPU 上運(yùn)行。
你可以將算法、向量化、并行文件處理或更多GPU 語言等主題添加到上面的列表中,也可以刪除某個(gè)主題,以便將更多時(shí)間花在其他主題上。還有一些額外的章節(jié)將吸引學(xué)生繼續(xù)探索并行計(jì)算的世界。
關(guān)于代碼
如果不實(shí)際編寫代碼并運(yùn)行它,就無法學(xué)習(xí)并行計(jì)算。為此,我們?cè)跁刑峁┝舜罅康睦印?br />這些例子可掃描封底二維碼下載。你可以下載這些示例的完整集合或單獨(dú)按章節(jié)進(jìn)行下載。
在這些示例代碼、所涉及的軟件和硬件當(dāng)中不可避免地會(huì)有缺陷和錯(cuò)誤。如果你發(fā)現(xiàn)了錯(cuò)誤或不完整的內(nèi)容,我們鼓勵(lì)你對(duì)示例進(jìn)行反饋。我們已經(jīng)合并了一些來自讀者的更改請(qǐng)求,對(duì)此我們非常感激。此外,源代碼存儲(chǔ)庫是查找修正和討論源代碼的最佳地方。
參考資料和習(xí)題答案
可掃描封底二維碼下載。
軟件與硬件需求
也許并行和高性能計(jì)算的最大挑戰(zhàn)是所用到的廣泛的硬件和軟件。在過去,這些專門的系統(tǒng)只能在特定的環(huán)境下使用。最近,硬件和軟件變得更加大眾化,甚至在臺(tái)式機(jī)或筆記本電腦上都可以廣泛使用。這是一個(gè)重大轉(zhuǎn)變,可讓高性能計(jì)算程序更容易開發(fā)。然而,硬件和軟件環(huán)境的設(shè)置仍然是該任務(wù)中最困難的部分。如果你可以訪問已經(jīng)配置好的并行計(jì)算集群,我們鼓勵(lì)你利用它。最
后,你可能希望設(shè)置自己的計(jì)算環(huán)境。這些示例在Linux 或UNIX 系統(tǒng)上是最容易使用的,但許多情況下也可在Windows 和macOS 上運(yùn)行,只是需要做一些額外更改。如果你發(fā)現(xiàn)某個(gè)示例不能在系統(tǒng)上運(yùn)行,我們提供了Docker 容器模板和VirtualBox 設(shè)置腳本作為替代方案。
關(guān)于GPU 的練習(xí),需要使用來自不同硬件制造商的GPU,包括NVIDIA、AMD Radeon 和Intel。
安裝GPU 圖形驅(qū)動(dòng)程序仍然是設(shè)置本地運(yùn)行環(huán)境遇到的最大困難。一些GPU 語言也可以在CPU上工作,從而允許在本地環(huán)境中為你沒有的硬件開發(fā)代碼。你可能還會(huì)發(fā)現(xiàn)在CPU 上調(diào)試更加容易,但是為了看到真實(shí)性能,你還必須安裝GPU 硬件。
其他需要特殊安裝的示例包括批處理系統(tǒng)和并行文件示例。為了更加接近真實(shí)情況,批處理系統(tǒng)需要在多臺(tái)筆記本電腦或者工作站上進(jìn)行設(shè)置。類似地,并行文件示例最適合使用像Lustre 這樣的專門文件系統(tǒng),但其他的基本示例可在單獨(dú)的筆記本電腦或工作站上運(yùn)行。
關(guān)于封面插圖
本書封面上的人物插圖標(biāo)題是Mde de brosses à Vienne,即《維也納的刷子銷售商》。該插圖取自 Jacques Grasset de Saint-Sauveur(17571810 年)收集的各國禮服畫集,名為Costumes de Différents Pays,于1797 年在法國出版。其中的每幅插圖都是經(jīng)手工精細(xì)繪制并上色的。Jacques Grassetde Saint-Sauveur 豐富多樣的收藏生動(dòng)地提醒我們,僅在200 年前,世界上的城鎮(zhèn)和地區(qū)在文化上存在很大的差異。那時(shí),人們彼此隔絕,說著不同的方言或語言;無論是在街上還是在鄉(xiāng)下,只要看他們的衣著,就很容易看出他們住在哪里,從事什么職業(yè)或處于什么地位。
從那時(shí)起,我們的著裝方式發(fā)生了變化,當(dāng)時(shí)非常豐富的地域多樣性已經(jīng)消失。現(xiàn)在,已很難區(qū)分不同國家的居民,更不用說不同的城鎮(zhèn)或地區(qū)了。也許我們已經(jīng)用文化的多樣性換取了更多樣化的個(gè)人生活當(dāng)然,指的是更多樣化和快節(jié)奏的技術(shù)生活。在當(dāng)前這個(gè)電腦書籍同質(zhì)化嚴(yán)重的時(shí)代,Manning 出版社用兩個(gè)世紀(jì)前地區(qū)生活的豐富多樣性的書籍封面來慶祝電腦行業(yè)的發(fā)明創(chuàng)造和首創(chuàng)精神,這些書被Jacques Grasset de Saint-Sauveur 的圖片重新賦予了生命。
Robert Robey在洛斯阿拉莫斯國家實(shí)驗(yàn)室工作,30多年來一直活躍在并行計(jì)算領(lǐng)域。Yuliana Zamora目前是芝加哥大學(xué)的博士生及Siebel學(xué)者,曾在許多國家會(huì)議上講授現(xiàn)代硬件編程技術(shù)。
第Ⅰ部分 并行計(jì)算介紹
第1 章 為什么使用并行計(jì)算 3
1.1 為什么要學(xué)習(xí)并行計(jì)算 5
1.1.1 并行計(jì)算的潛在優(yōu)勢(shì)是什么 7
1.1.2 并行計(jì)算的注意事項(xiàng) 9
1.2 并行計(jì)算的基本定律 9
1.2.1 并行計(jì)算的極限:Amdahl 定律 9
1.2.2 突破并行極限:Gustafson-Barsis定律 10
1.3 并行計(jì)算如何工作 12
1.3.1 應(yīng)用程序示例 13
1.3.2 當(dāng)今異構(gòu)并行系統(tǒng)的硬件模型 18
1.3.3 當(dāng)今異構(gòu)并行系統(tǒng)的應(yīng)用程序模型及軟件模型 21
1.4 對(duì)并行方法進(jìn)行分類 24
1.5 并行策略 25
1.6 并行加速與比較加速:兩種不同的衡量標(biāo)準(zhǔn) 26
1.7 你將在本書中學(xué)到哪些內(nèi)容 27
1.7.1 擴(kuò)展閱讀 27
1.7.2 練習(xí) 28
1.8 本章小結(jié) 28
第2 章 規(guī)劃并行化 29
2.1 處理新項(xiàng)目:準(zhǔn)備工作 30
2.1.1 版本控制:為并行代碼創(chuàng)建一個(gè)安全的存儲(chǔ)庫 31
2.1.2 測試套件:創(chuàng)建健壯、可靠的應(yīng)用程序的第一步 32
2.1.3 查找和修復(fù)內(nèi)存問題 40
2.1.4 提高代碼的可移植性 41
2.2 概要分析:探測系統(tǒng)功能和應(yīng)用程序性能之間的差距 42
2.3 計(jì)劃:成功的基礎(chǔ) 42
2.3.1 探索benchmark 和mini-apps 43
2.3.2 核心數(shù)據(jù)結(jié)構(gòu)和代碼模塊化設(shè)計(jì) 43
2.3.3 算法:重新設(shè)計(jì)并行 44
2.4 實(shí)施 44
2.5 提交:高質(zhì)量的打包過程 45
2.6 進(jìn)一步探索 46
2.6.1 擴(kuò)展閱讀 46
2.6.2 練習(xí) 46
2.7 本章小結(jié) 46
第3 章 性能極限與分析 49
3.1 了解應(yīng)用程序的潛在性能限制 49
3.2 了解硬件性能:基準(zhǔn)測試 52
3.2.1 用于收集系統(tǒng)特征的工具 52
3.2.2 計(jì)算浮點(diǎn)運(yùn)算的最大理論值 55
3.2.3 內(nèi)存層級(jí)和理論內(nèi)存帶寬 55
3.2.4 帶寬和浮點(diǎn)運(yùn)算的實(shí)證測量 56
3.2.5 計(jì)算flop 和帶寬之間的機(jī)器平衡 59
3.3 描述你的應(yīng)用程序:分析 59
3.3.1 分析工具 60
3.3.2 處理器時(shí)鐘頻率和能耗的實(shí)證測量 69
3.3.3 在運(yùn)行時(shí)跟蹤內(nèi)存 70
3.4 進(jìn)一步探索 71
3.4.1 擴(kuò)展閱讀 71
3.4.2 練習(xí) 71
3.5 本章小結(jié) 71
第4 章 數(shù)據(jù)設(shè)計(jì)和性能模型 73
4.1 數(shù)據(jù)結(jié)構(gòu)與性能:面向數(shù)據(jù)的設(shè)計(jì) 74
4.1.1 多維數(shù)組 76
4.1.2 結(jié)構(gòu)數(shù)組(AoS)與數(shù)組結(jié)構(gòu)(SoA) 80
4.1.3 數(shù)組結(jié)構(gòu)的數(shù)組(AoSoA) 85
4.2 緩存未命中的3C:強(qiáng)制、容量與沖突 86
4.3 簡單性能模型:案例研究 90
4.3.1 全矩陣數(shù)據(jù)表示 92
4.3.2 壓縮稀疏存儲(chǔ)表示 95
4.4 高級(jí)性能模型 98
4.5 網(wǎng)絡(luò)消息 101
4.6 進(jìn)一步探索 103
4.6.1 擴(kuò)展閱讀 104
4.6.2 練習(xí) 104
4.7 本章小結(jié) 104
第5 章 并行算法與模式 105
5.1 并行計(jì)算應(yīng)用的算法分析 105
5.2 性能模型與算法復(fù)雜性 106
5.3 什么是并行算法 109
5.4 什么是哈希函數(shù) 110
5.5 空間哈希:一種高并行度算法 111
5.5.1 使用完美哈希進(jìn)行空間網(wǎng)格操作 113
5.5.2 使用緊湊哈希進(jìn)行空間網(wǎng)格操作 126
5.6 prefix sum(掃描)模式及其在并行計(jì)算中的重要性 132
5.6.1 Step-efficient 并行掃描操作 133
5.6.2 Work-efficient 并行掃描操作 134
5.6.3 用于大型數(shù)組的并行掃描操作 135
5.7 并行全局和:解決關(guān)聯(lián)性問題 135
5.8 并行算法研究的未來 141
5.9 進(jìn)一步探索 141
5.9.1 擴(kuò)展閱讀 141
5.9.2 練習(xí) 142
5.10 本章小結(jié) 142
第II 部分 CPU:并行的主力第6 章 向量化:免費(fèi)的flop 145
6.1 向量及單指令多數(shù)據(jù)流(SIMD)概要 145
6.2 向量化的硬件趨勢(shì) 146
6.3 向量化方法 147
6.3.1 使用優(yōu)化軟件庫可以輕松提高性能 148
6.3.2 自動(dòng)向量化:向量化加速的簡單方法(大多數(shù)情況下) 148
6.3.3 通過提示來指導(dǎo)編譯器:pragma和指令 152
6.3.4 使用向量本征庫處理無法向量化的循環(huán) 157
6.3.5 大膽嘗試:使用匯編代碼進(jìn)行向量化 162
6.4 實(shí)現(xiàn)更好向量化的編程風(fēng)格 163
6.5 與編譯器向量化相關(guān)的編譯器標(biāo)志 164
6.6 使用OpenMP SIMD 指令實(shí)現(xiàn)更好的移植性 170
6.7 進(jìn)一步探索 172
6.7.1 擴(kuò)展閱讀 172
6.7.2 練習(xí) 172
6.8 本章小結(jié) 173
第7 章 使用OpenMP 實(shí)現(xiàn)并行計(jì)算 175
7.1 OpenMP 介紹 175
7.1.1 OpenMP 概念 176
7.1.2 OpenMP 簡單程序示例 179
7.2 典型的OpenMP 用例:循環(huán)級(jí)OpenMP、高級(jí)OpenMP 和MPI OpenMP 183
7.2.1 使用循環(huán)級(jí)OpenMP 進(jìn)行快速并行化 184
7.2.2 使用高級(jí)OpenMP 獲得更好的并行度 184
7.2.3 使用MPI OpenMP 獲得極限可擴(kuò)展性 185
7.3 標(biāo)準(zhǔn)循環(huán)級(jí)OpenMP 示例 185
7.3.1 循環(huán)級(jí)OpenMP:向量加法示例 186
7.3.2 stream triad 示例 189
7.3.3 循環(huán)級(jí)OpenMP:stencil 示例 190
7.3.4 循環(huán)級(jí)示例的性能 191
7.3.5 使用OpenMP 線程的global sum的約減示例 192
7.3.6 循環(huán)級(jí)OpenMP 的潛在問題 193
7.4 OpenMP 中變量范圍對(duì)結(jié)果準(zhǔn)確性的重要性 193
7.5 函數(shù)級(jí)OpenMP:使整個(gè)函數(shù)實(shí)現(xiàn)線程并行 194
7.6 使用高級(jí)OpenMP 改進(jìn)并行可伸縮性 196
7.6.1 如何實(shí)現(xiàn)高級(jí)OpenMP 197
7.6.2 實(shí)現(xiàn)高級(jí)OpenMP 的示例 199
7.7 使用OpenMP 混合線程及向量化 201
7.8 使用OpenMP 的高級(jí)示例 204
7.8.1 在x 和y 方向單獨(dú)傳遞的stencil示例 204
7.8.2 使用OpenMP 線程實(shí)現(xiàn)kahan求和 208
7.8.3 通過線程實(shí)現(xiàn)的prefix scan算法 209
7.9 線程工具對(duì)健壯程序的重要性 210
7.9.1 使用Allinea/ARM MAP快速獲得應(yīng)用程序的高層概要文件 211
7.9.2 使用Intel Inspector 查找線程競態(tài)條件 212
7.10 基于任務(wù)的支持算法示例 213
7.11 進(jìn)一步探索 214
7.11.1 擴(kuò)展閱讀 214
7.11.2 練習(xí) 215
7.12 本章小結(jié) 215
第8 章 MPI:并行骨干 217
8.1 MPI 程序基礎(chǔ) 217
8.1.1 為每個(gè)MPI 程序進(jìn)行基本MPI函數(shù)調(diào)用 218
8.1.2 簡單MPI 程序的編譯器包裝器 219
8.1.3 使用并行啟動(dòng)命令 219
8.1.4 MPI 程序的最小工作示例 219
8.2 用于進(jìn)程間通信的發(fā)送和接收命令 221
8.3 聚合通信:MPI 的強(qiáng)大組件 227
8.3.1 使用barrier 來同步計(jì)時(shí)器 228
8.3.2 使用廣播處理小文件輸入 228
8.3.3 使用約減從所有進(jìn)程中獲取單個(gè)值 230
8.3.4 使用gather 在調(diào)試打印輸出中排序 233
8.3.5 使用scatter 和gather 將數(shù)據(jù)發(fā)送到工作進(jìn)程 234
8.4 數(shù)據(jù)并行示例 236
8.4.1 使用stream triad 來測量節(jié)點(diǎn)上的帶寬 236
8.4.2 二維網(wǎng)格中的ghost cell 交換 238
8.4.3 三維stencil 計(jì)算中的ghost cell交換 244
8.5 使用高級(jí)MPI 功能來簡化代碼和啟用優(yōu)化 245
8.5.1 使用自定義MPI 數(shù)據(jù)類型來簡化代碼并提升性能 245
8.5.2 MPI 中的笛卡兒拓?fù)?250
8.5.3 ghost cell 交換變體的性能測試 255
8.6 通過聯(lián)合使用MPI 和OpenMP實(shí)現(xiàn)極高的可擴(kuò)展性 257
8.6.1 混合MPI 和OpenMP 的優(yōu)勢(shì) 257
8.6.2 MPI 與OpenMP 混合示例 258
8.7 進(jìn)一步探索 259
8.7.1 擴(kuò)展閱讀 260
8.7.2 練習(xí) 260
8.8 本章小結(jié) 261
第III 部分 GPU:加速應(yīng)用程序運(yùn)行
第9 章 GPU 架構(gòu)及概念 265
9.1 作為加速計(jì)算平臺(tái)的CPU-GPU
系統(tǒng) 266
9.1.1 集成GPU:商業(yè)化系統(tǒng)中沒有被充分使用的資源 267
9.1.2 獨(dú)立GPU:高性能計(jì)算的主力 267
9.2 GPU 和線程引擎 268
9.2.1 使用流多處理器(或子片)作為計(jì)算單元 270
9.2.2 作為獨(dú)立處理器的處理單元 270
9.2.3 每個(gè)處理單元進(jìn)行多個(gè)數(shù)據(jù)操作 270
9.2.4 計(jì)算最新GPU flop 的理論峰值 270
9.3 GPU 內(nèi)存空間的特點(diǎn) 272
9.3.1 計(jì)算內(nèi)存帶寬的理論峰值 273
9.3.2 測量GPU stream benchmark 274
9.3.3 GPU 的Roofline 性能模型 275
9.3.4 使用mixbench 性能工具為工作負(fù)載選擇最佳GPU 276
9.4 PCI 總線:CPU 與GPU 之間的數(shù)據(jù)傳輸橋梁 278
9.4.1 PCI 總線的理論帶寬 279
9.4.2 PCI 帶寬benchmark 應(yīng)用程序 281
9.5 多GPU 平臺(tái)和MPI 284
9.5.1 優(yōu)化網(wǎng)絡(luò)中GPU 之間的數(shù)據(jù)移動(dòng) 284
9.5.2 一種比PCI 總線性能更高的替代方案 285
9.6 GPU 加速平臺(tái)的潛在收益 286
9.6.1 縮短解決問題的時(shí)間 286
9.6.2 使用GPU 降低能耗 287
9.6.3 使用GPU 降低云計(jì)算成本 292
9.7 何時(shí)使用GPU 292
9.8 進(jìn)一步探索 292
9.8.1 擴(kuò)展閱讀 293
9.8.2 練習(xí) 293
9.9 本章小結(jié) 293
第10 章 GPU 編程模型 295
10.1 GPU 編程抽象:通用框架 296
10.1.1 大規(guī)模并行處理 296
10.1.2 無法在任務(wù)之間進(jìn)行協(xié)調(diào) 297
10.1.3 GPU 并行性的術(shù)語 297
10.1.4 將數(shù)據(jù)分解成獨(dú)立的工作單元:NDRange 或網(wǎng)格 297
10.1.5 為工作組提供大小合適的工作塊 300
10.1.6 通過lockstep 執(zhí)行子工作組、warp 與wavefront 300
10.1.7 工作項(xiàng):操作的基本單元 301
10.1.8 SIMD 或向量硬件 301
10.2 GPU 編程模型的代碼結(jié)構(gòu) 302
10.2.1 Me編程:并行kernel的概念 302
10.2.2 線程索引:將本地tile 映射到全局中 303
10.2.3 索引集 304
10.2.4 如何在GPU 編程模型中對(duì)內(nèi)存資源進(jìn)行尋址 305
10.3 優(yōu)化GPU 資源利用 306
10.3.1 kernel 將使用多少寄存器 307
10.3.2 利用率:提高工作組的負(fù)載率 307
10.4 約減模式需要跨工作組進(jìn)行同步 309
10.5 通過隊(duì)列(流)進(jìn)行異步計(jì)算 310
10.6 為GPU 定制并行化應(yīng)用程序的策略 311
10.6.1 場景1:三維大氣環(huán)境仿真 311
10.6.2 場景2:非結(jié)構(gòu)化網(wǎng)格應(yīng)用 312
10.7 進(jìn)一步探索 312
10.7.1 擴(kuò)展閱讀 313
10.7.2 練習(xí) 314
10.8 本章小結(jié) 314
第11 章 基于指令的GPU 編程 315
11.1 為GPU 實(shí)現(xiàn)應(yīng)用編譯指令和pragma 的過程 316
11.2 OpenACC:在GPU 上運(yùn)行的最簡單方法 317
11.2.1 編譯OpenACC 代碼 319
11.2.2 OpenACC 中用于加速計(jì)算的并行計(jì)算區(qū)域 320
11.2.3 使用指令減少CPU 和GPU之間的數(shù)據(jù)移動(dòng) 325
11.2.4 優(yōu)化GPU kernel 329
11.2.5 stream triad 性能結(jié)果的總結(jié) 334
11.2.6 高級(jí)OpenACC 技術(shù) 335
11.3 OpenMP:加速器領(lǐng)域的重量級(jí)選手 337
11.3.1 編譯OpenMP 代碼 337
11.3.2 使用OpenMP 在GPU 上生成并行工作 339
11.3.3 使用OpenMP 創(chuàng)建數(shù)據(jù)區(qū)域來控制到GPU 的數(shù)據(jù)移動(dòng) 342
11.3.4 為GPU 優(yōu)化OpenMP 346
11.3.5 用于GPU 的高級(jí)OpenMP 350
11.4 進(jìn)一步探索 353
11.4.1 擴(kuò)展閱讀 353
11.4.2 練習(xí) 354
11.5 本章小結(jié) 355
第12 章 GPU 語言:深入了解基礎(chǔ)知識(shí) 357
12.1 原生GPU 編程語言的特性 358
12.2 CUDA 和HIP GPU 語言:底層性能選項(xiàng) 359
12.2.1 編寫和構(gòu)建第一個(gè)CUDA應(yīng)用程序 360
12.2.2 CUDA 的約減kernel:事情變得復(fù)雜 367
12.2.3 Hipifying CUDA 代碼 372
12.3 OpenCL:用于可移植的開源GPU 語言 375
12.3.1 編寫和構(gòu)建第一個(gè)OpenCL應(yīng)用程序 376
12.3.2 OpenCL 中的約減 381
12.4 SYCL:一個(gè)成為主流的實(shí)驗(yàn)性C 實(shí)現(xiàn) 384
12.5 性能可移植性的高級(jí)語言 387
12.5.1 Kokkos:性能可移植性生態(tài)系統(tǒng) 387
12.5.2 RAJA 提供更具適應(yīng)性的性能可移植性層 390
12.6 進(jìn)一步探索 392
12.6.1 擴(kuò)展閱讀 392
12.6.2 練習(xí) 393
12.7 本章小結(jié) 393
第13 章 GPU 配置分析及工具 395
13.1 分析工具概要 395
13.2 如何選擇合適的工作流 396
13.3 問題示例:淺水仿真 397
13.4 分析工作流的示例 400
13.4.1 運(yùn)行淺水應(yīng)用程序 400
13.4.2 分析CPU 代碼來制定行動(dòng)計(jì)劃 402
13.4.3 為實(shí)施步驟添加OpenACC計(jì)算指令 403
13.4.4 添加數(shù)據(jù)移動(dòng)指令 405
13.4.5 通過引導(dǎo)分析獲取改進(jìn)建議 406
13.4.6 強(qiáng)大的輔助開發(fā)工具:NVIDIA Nsight 工具套件 408
13.4.7 用于AMD GPU 生態(tài)系統(tǒng)的CodeXL 409
13.5 專注于重要指標(biāo) 409
13.5.1 利用率:是否有足夠的工作量 410
13.5.2 發(fā)布效率:你的warp 是否經(jīng)常停滯? 410
13.5.3 獲得帶寬 411
13.6 使用容器和虛擬機(jī)來提供備用工作流 411
13.6.1 將Docker 容器作為解決方案 411
13.6.2 使用VirtualBox 虛擬機(jī) 413
13.7 移入云端:提供靈活和可擴(kuò)展能力 415
13.8 進(jìn)一步探索 415
13.8.1 擴(kuò)展閱讀 415
13.8.2 練習(xí) 416
13.9 本章小結(jié) 416
第Ⅳ部分 高性能計(jì)算生態(tài)系統(tǒng)
第14 章 關(guān)聯(lián)性:與kernel 休戰(zhàn) 419
14.1 為什么關(guān)聯(lián)性很重要 420
14.2 探索架構(gòu) 421
14.3 OpenMP 的線程關(guān)聯(lián) 422
14.4 進(jìn)程關(guān)聯(lián)性與MPI 429
14.4.1 OpenMPI 的默認(rèn)進(jìn)程放置 429
14.4.2 進(jìn)行控制:在OpenMPI 中指定進(jìn)程放置的基本技術(shù) 430
14.4.3 關(guān)聯(lián)性不僅僅是進(jìn)程綁定:全面討論 434
14.5 MPI OpenMP 的關(guān)聯(lián)性 436
14.6 從命令行控制關(guān)聯(lián)性 440
14.6.1 使用hwloc-bind 分配關(guān)聯(lián)性 440
14.6.2 使用likwid-pin: likwid 工具套件中的關(guān)聯(lián)工具 441
14.7 展望未來:在運(yùn)行時(shí)設(shè)置和更改關(guān)聯(lián)性 443
14.7.1 在可執(zhí)行文件中設(shè)置關(guān)聯(lián)性 443
14.7.2 在運(yùn)行時(shí)更改進(jìn)程關(guān)聯(lián)性 445
14.8 進(jìn)一步探索 447
14.8.1 擴(kuò)展閱讀 447
14.8.2 練習(xí) 448
14.9 本章小結(jié) 449
第15 章 批處理調(diào)度器:為混亂帶來秩序 451
15.1 無管理系統(tǒng)所帶來的混亂 452
15.2 如何順利地在繁忙的集群中部署任務(wù) 452
15.2.1 繁忙集群中的批處理系統(tǒng)布局 453
15.2.2 如何合理地在繁忙的集群和HPC 站點(diǎn)上運(yùn)行任務(wù):HPC 中的推薦做法 453
15.3 提交第一個(gè)批處理腳本 454
15.4 為長時(shí)間運(yùn)行的作業(yè)設(shè)定自動(dòng)重啟 459
15.5 在批處理腳本中指定依賴項(xiàng) 463
15.6 進(jìn)一步探索 465
15.6.1 擴(kuò)展閱讀 465
15.6.2 練習(xí) 465
15.7 本章小結(jié) 466
第16 章 并行環(huán)境的文件操作 467
16.1 高性能文件系統(tǒng)的組成部分 467
16.2 標(biāo)準(zhǔn)文件操作:并行到串行(parallel-to-serial)接口 468
16.3 在并行環(huán)境中使用MPI
文件操作(MPI-IO) 469
16.4 HDF5 具有自我描述功能,可更好地管理數(shù)據(jù) 477
16.5 其他并行文件軟件包 485
16.6 并行文件系統(tǒng):硬件接口 485
16.6.1 并行文件設(shè)置 485
16.6.2 適用于所有文件系統(tǒng)的通用提示 489
16.6.3 特定文件系統(tǒng)的提示 490
16.7 進(jìn)一步探索 493
16.7.1 擴(kuò)展閱讀 493
16.7.2 練習(xí) 494
16.8 本章小結(jié) 494
第17 章 用于編寫優(yōu)質(zhì)代碼的工具和資源 495
17.1 版本控制系統(tǒng):一切從這里開始 497
17.1.1 分布式版本控制更適合全局協(xié)作 498
17.1.2 通過集中版本控制來簡化操作并提高代碼安全 498
17.2 用于跟蹤代碼性能的計(jì)時(shí)器例程 499
17.3 分析器:不去衡量就無法提升 500
17.3.1 日常使用的基于文本的分析器 501
17.3.2 用于快速識(shí)別瓶頸的高級(jí)分析器 502
17.3.3 使用中級(jí)分析器來指導(dǎo)應(yīng)用程序開發(fā) 502
17.3.4 通過詳細(xì)分析器了解硬件性能的細(xì)節(jié)信息 504
17.4 benchmark 和mini-apps:了解系統(tǒng)性能的窗口 504
17.4.1 使用benchmark 測量系統(tǒng)性能特征 504
17.4.2 通過mini-apps 提供應(yīng)用程序的視角 505
17.5 為健壯的應(yīng)用程序檢測及修復(fù)內(nèi)存錯(cuò)誤 507
17.5.1 valgrind Memcheck:備用開源方案 507
17.5.2 使用Dr. Memory 診斷內(nèi)存問題 507
17.5.3 對(duì)于要求嚴(yán)苛的應(yīng)用程序使用商業(yè)內(nèi)存檢測工具 509
17.5.4 使用基于編譯器的內(nèi)存工具來簡化操作 509
17.5.5 通過Fence-post 檢查器來檢測越界內(nèi)存訪問 510
17.5.6 GPU 應(yīng)用程序所使用的內(nèi)存工具 511
17.6 用于檢測競態(tài)條件的線程檢查器 512
17.6.1 Intel Inspector:帶有GUI 的競態(tài)條件檢測工具 512
17.6.2 Archer:一個(gè)基于文本的檢測競態(tài)條件的工具 512
17.7 Bug-busters:用于消除bug 的調(diào)試器 514
17.7.1 在HPC 站點(diǎn)中廣泛使用的TotalView 調(diào)試器 514
17.7.2 DDT:另一種在HPC 站點(diǎn)廣泛使用的調(diào)試器 514
17.7.3 Linux 調(diào)試器:為本地開發(fā)需求提供免費(fèi)的替代方案 515
17.7.4 通過GPU 調(diào)試器消除GPU bug 515
17.8 文件操作分析 516
17.9 包管理器:你的個(gè)人系統(tǒng)管理員 519
17.9.1 macOS 的包管理器 519
17.9.2 Windows 包管理器 519
17.9.3 Spack 包管理器:用于高性能計(jì)算的包管理器 519
17.10 模塊:加載專門的工具鏈 520
17.10.1 TCL modules:用于加載軟件工具鏈的原始模塊系統(tǒng) 522
17.10.2 Lmod:基于Lua 的替代模塊實(shí)現(xiàn) 523
17.11 思考與練習(xí) 523
17.12 本章小結(jié) 523
附錄A 參考資料 (可從配書網(wǎng)站下載)
附錄B 習(xí)題答案 (可從配書網(wǎng)站下載)