OpenMP日益增加的復雜性使其學習門檻不斷升高,本書回歸OpenMP zui初的設計哲學,提煉出大多數(shù)程序員常用的21項核心知識——稱為OpenMP“通用核心”,為零基礎讀者搭建了從通用核心到OpenMP多線程編程的高效學習階梯。本書由OpenMP技術專家撰寫,內容涵蓋并行計算的核心設計模式、共享工作循環(huán)構造、OpenMP數(shù)據(jù)環(huán)境、OpenMP任務和OpenMP內存模型等內容,采用編程驅動的方式,借助復雜性逐漸提高的實例來逐步引入新概念。此外,本書網(wǎng)站ompcore.com為讀者免費提供各類代碼示例和練習題。
本書不是OpenMP的參考指南,在OpenMP網(wǎng)站上可以找到該語言的參考指南,將其和OpenMP規(guī)范結合起來就能提供你所需要的信息。此外,也可以將Ruud van der Pas、Eric Stotzer和Christian Terboven[13]所著的Using OpenMP桾he Next Step這本優(yōu)秀的書作為參考指南。
本書是關于如何學習OpenMP的。我們假設讀者沒有多線程的經驗,也沒有OpenMP的知識。我們將材料分塊有序引入,以便讀者有效地學習這門語言。這與參考指南不同,在參考指南中,你會通過系統(tǒng)的關鍵元素來逐一了解每個元素的完整描述。在本書中,我們介紹了一些想法和支持這些想法的OpenMP構造(construct)。然后,在引入更復雜的想法時,我們會重新審視OpenMP構造,并描述該構造的其他方面。對于任何一個給定的OpenMP構造,關于能用它做的一切事情的完整描述可能分散在幾個章節(jié)中。
這樣的安排是不會出現(xiàn)在參考指南中的。但正如你希望看到的那樣,這對于學習一門新的編程語言來說是非常有益的。例如,在教孩子數(shù)學函數(shù)的概念時,你永遠不會在接近奇點時引入極限和函數(shù)值的概念。你會等待,往往是很多年后,當孩子掌握了函數(shù)的概念后,而且是通過長期的練習掌握后,再引入極限來完成函數(shù)的完整定義。同樣,對于OpenMP也是如此。在介紹創(chuàng)建線程的并行構造(parallel construct)時,解釋所有控制數(shù)據(jù)環(huán)境的機制會讓人難以接受。不如先介紹線程的創(chuàng)建以及如何利用線程做有用的工作。然后,在掌握了管理線程的基礎知識后,再回到線程創(chuàng)建,但此時擁有了控制數(shù)據(jù)環(huán)境的能力。
使用本書的關鍵是主動地跟隨本書練習。下載一個OpenMP編譯器(gcc編譯器和大多數(shù)商業(yè)編譯器一樣支持OpenMP)。隨著每個OpenMP指令或API例程的引入,編寫程序進行實驗。以不同的方式使用它們,理解它們的工作原理,然后再繼續(xù)閱讀。在寫代碼之前,不要只把書從頭到尾讀一遍,暫停一下,邊看書邊寫代碼。
為了支持這種主動學習的方式,本書網(wǎng)站(http://www.ompcore.com)提供了各種各樣的程序和練習。請經常查閱該網(wǎng)站,我們會持續(xù)更新,不斷分享關于OpenMP通用核心的新知識。
最后說一下編程語言。OpenMP支持C、C++和Fortran,理想的情況是本書應該包含這三種語言的例子。然而,這樣做會大大擴大本書的篇幅和范圍,對讀者來說,這些額外的工作真的沒有什么好處。除了極少數(shù)的例外情況(書中有詳細說明),OpenMP在三種語言之間基本上是一樣的,知道了一種語言的OpenMP,就會知道三種語言的OpenMP。因此,我們選擇為C/C++和Fortran定義構造,但書中的例子和大部分的討論都以C語言為主。我們認為這是一個正確的折中方案,因為在高性能計算領域,C語言是程序員要掌握的最基本的知識,即使是主要編寫Fortran代碼的程序員,也要了解C語言的基礎知識。
為了幫助使用Fortran的讀者,我們在本書網(wǎng)站上提供了所有例子的Fortran版本。對于少數(shù)不懂C語言的Fortran程序員,我們還提供了C語言的簡短教程。我們相信,本書與這些在線資源對Fortran程序員來說是重要的學習資料。因此,請不要因為滿篇的C代碼而使你對本書望而卻步。如果你想學習OpenMP,無論是用C、C++還是Fortran編程,本書都會對你有所幫助。
致謝
本書的內容是在20年的OpenMP教學基礎上煞費苦心地開發(fā)出來的。例子、材料的組織流程和概念的描述方式等,都是由講師團隊在各種超級計算會議的講座上研究出來的。我們要特別感謝Mark Bull(EPCC)、Sanjiv Shah(Intel)、Barbara Chapman(石溪大學)、Larry Meadows(Intel)、Paul Petersen(Intel)和Simon McIntosh-Smith(布里斯托大學)。內存模型的內容整合起來特別困難,田新民(Intel)、Michael Klemm(Intel),特別是Deepak Eachempati(Cray)在幫助我們定義這些材料方面發(fā)揮了重要作用。為了開發(fā)內存模型的例子,我們需要訪問各種各樣的架構。Simon McIntosh-Smith給予我們非常大的幫助,協(xié)助我們訪問布里斯托大學的Isambard系統(tǒng)。
我們非常感謝MIT出版社的審稿團隊。在從定稿到出版的過程中,他們的反饋對我們幫助很大。在這個團隊中,我們特別要提到Ruud van der Pas(Oracle)。Ruud是我們的好朋友,他從一開始就鼓勵我們參與這個項目。他對本書進行了非常仔細的審閱,做出了超出其職責范圍的貢獻。
我們還要感謝OpenMP架構審查委員會允許我們使用OpenMP規(guī)范和部分示例文檔。最后,我們要感謝整個OpenMP社區(qū)的人:Bronis de Supinski(LLNL)和他領導的OpenMP語言委員會,與我們合作過的OpenMP程序員,以及過去使用過我們的教程的所有學生。沒有他們,我們不可能創(chuàng)作出這樣的書。
譯者序
序言
前言
第一部分 做好學習OpenMP的準備
第1章 并行計算 2
1.1 并行計算的基本概念 2
1.2 并發(fā)性的興起 4
1.3 并行硬件 5
1.3.1 多處理器系統(tǒng) 5
1.3.2 圖形處理單元 8
1.3.3 分布式內存集群 10
1.4 多處理器計算機的并行軟件 10
第2章 性能語言 13
2.1 基礎:FLOPS、加速比和并行效率 13
2.2 阿姆達爾定律 16
2.3 并行開銷 17
2.4 強擴展與弱擴展 19
2.5 負載均衡 19
2.6 用roofline模型理解硬件 21
第3章 什么是OpenMP 23
3.1 OpenMP的歷史 23
3.2 通用核心 25
3.3 OpenMP的主要組件 26
第二部分 OpenMP通用核心
第4章 線程和OpenMP編程模型 31
4.1 OpenMP概述 31
4.2 OpenMP 程序的結構 31
4.3 線程和fork-join模式 34
4.4 使用線程 38
4.4.1 SPMD設計模式 39
4.4.2 偽共享 43
4.4.3 同步 45
4.5 結束語 49
第5章 并行化循環(huán) 50
5.1 共享工作循環(huán)構造 51
5.2 組合式并行共享工作循環(huán)構造 53
5.3 歸約 54
5.4 循環(huán)調度 56
5.4.1 靜態(tài)調度 56
5.4.2 動態(tài)調度 57
5.4.3 選擇一個調度 59
5.5 隱式柵欄和nowait子句 61
5.6 帶有并行循環(huán)共享工作的Pi程序 63
5.7 一種循環(huán)級并行策略 64
5.8 結束語 66
第6章 OpenMP數(shù)據(jù)環(huán)境 67
6.1 缺省存儲屬性 68
6.2 修改存儲屬性 70
6.2.1 shared子句 70
6.2.2 private子句 72
6.2.3 firstprivate子句 73
6.2.4 default子句 74
6.3 數(shù)據(jù)環(huán)境的例子 74
6.3.1 數(shù)據(jù)作用域測試 75
6.3.2 曼德勃羅集的面積 76
6.3.3 重新審視Pi循環(huán)的例子 79
6.4 數(shù)組和指針 80
6.5 結束語 81
第7章 OpenMP任務 83
7.1 任務的必要性 83
7.2 顯式任務 86
7.3 第一個例子:薛定諤程序 87
7.4 single構造 88
7.5 使用任務 89
7.5.1 什么時候任務完成 90
7.6 任務的數(shù)據(jù)環(huán)境 91
7.6.1 任務的缺省數(shù)據(jù)作用域 91
7.6.2 利用任務重新審視鏈表程序 93
7.7 利用任務的基礎設計模式 93
7.7.1 分而治之模式 95
7.8 結束語 99
第8章 OpenMP內存模型 100
8.1 重新審視內存層次結構 101
8.2 OpenMP通用核心內存模型 103
8.3 使用共享內存 106
8.4 結束語 108
第9章 通用核心回顧 110
9.1 管理線程 111
9.2 共享工作構造 111
9.3 組合式并行共享工作循環(huán)構造 113
9.4 OpenMP任務 113
9.5 同步和內存一致性模型 114
9.6 數(shù)據(jù)環(huán)境子句 115
9.7 歸約子句 116
9.8 環(huán)境變量和運行時庫例程 117
第三部分 超越通用核心
第10章 超越通用核心的多線程 121
10.1 用于OpenMP通用核心構造的附加子句 121
10.1.1 并行構造 122
10.1.2 共享工作循環(huán)構造 124
10.1.3 任務構造 129
10.2 通用核心中缺失的多線程功能 133
10.2.1 threadprivate 133
10.2.2 master 135
10.2.3 atomic 136
10.2.4 OMP_STACKSIZE 137
10.2.5 運行時庫例程 138
10.3 結束語 140
第11章 同步和OpenMP內存模型 141
11.1 內存一致性模型 142
11.2 成對同步 146
11.3 鎖以及如何使用它 151
11.4 C++內存模型和OpenMP 153
11.5 結束語 156
第12章 超越OpenMP通用核心的硬件 157
12.1 非統(tǒng)一內存訪問系統(tǒng) 158
12.1.1 在NUMA系統(tǒng)上工作 159
12.1.2 嵌套并行構造 168
12.1.3 檢查線程親和力 171
12.1.4 小結:線程親和力和數(shù)據(jù)局部性 173
12.2 SIMD 173
12.3 設備構造 180
12.4 結束語 184
第13章 繼續(xù)OpenMP的學習 186
13.1 來自ARB的程序員資源 186
13.2 如何閱讀OpenMP規(guī)范 188
13.2.1 帶有所有正式術語的OpenMP 188
13.3 OpenMP規(guī)范的結構 191
13.4 結束語 193
術語表 194