前 言 2010年以來,中國超級計算機建設突飛猛進,欣欣向榮。一個原因是國力強盛,大力投資高新科技;另一個原因是整體科技水平提高,需求旺盛。天氣預報、石油物探、工程仿真、基因測序等傳統(tǒng)應用對計算資源的需求持續(xù)增長,以深度學習為代表的人工智能大爆發(fā),資金雄厚的互聯(lián)網(wǎng)公司對計算能力極度渴求。超級計算機的建設、應用主戰(zhàn)場正在從教育科研單位轉向科技企業(yè)。
為什么要寫這本書面對浩如煙海的數(shù)據(jù),CPU已經(jīng)力不從心,因此世界領先的超級計算機都裝備大量的加速器或者眾核處理器。
目前主流加速器產(chǎn)品是NVIDIA GPU、AMD GPU和Intel至強Phi協(xié)處理器。三種加速器使用的編程語言分別為CUDA C/CUDA Fortran、OpenCL和MIC導語。加速器計算有4個困難。
一是CUDA/OpenCL等低級語言編程難度大,且需要深入了解加速器的硬件結構。而大部分的用戶不是專業(yè)編程人員,學習一門新的編程技術將耗費大量時間。
二是加速器的計算模型與CPU差別很大,移植舊程序需要幾乎完全重寫。大量的舊程序在性能優(yōu)化上已經(jīng)千錘百煉,穩(wěn)定性上也久經(jīng)考驗,完全重寫是不可完成的任務。
三是低級編程語言開發(fā)的程序與硬件結構密切相關,硬件升級時必須升級軟件,否則將損失性能。而硬件每隔兩三年就升級一次,頻繁的軟件升級將給用戶帶來巨大負擔。
四是投資方向難以選擇。三種加速器均有自己獨特的編程語言,且互不兼容。用戶在投資建設硬件平臺、選擇軟件開發(fā)語言時就會陷入困境,不知三種設備中哪個會在競爭中勝出。如果所選加速器將來落敗,將會帶來巨大損失;而猶豫不決又將錯過技術變革的歷史機遇。
OpenACC應運而生,可以克服這4個困難。OpenACC的編程機制是,程序員只在原程序中添加少量編譯標識,編譯器根據(jù)作者的意圖自動產(chǎn)生低級語言代碼。無須學習新的編程語言和加速器硬件知識,便能迅速掌握。只添加少量編譯標識,不破壞原代碼,開發(fā)速度快,既可并行執(zhí)行又可恢復串行執(zhí)行。在硬件更新時,重新編譯一次代碼即可,不必手工修改代碼。OpenACC標準制定時就考慮了目前及將來的多種加速器產(chǎn)品,同一份代碼可以在多種加速器設備上編譯、運行,無成本切換硬件平臺。掌握OpenACC后,編寫程序省時、省力、省心。
本書特色筆者學習超算技術時有過苦淚:教材一上來就講技術細節(jié),只能機械地學習,不清楚這些算法、語法要解決什么問題,花費巨大精力后卻發(fā)現(xiàn)解決不了自己的難題;新技術的資料往往是英文的,而且零碎,還不一定準確,收集、學習成本很高,求助無門;科學計算領域的祖師語言Fortran現(xiàn)在有點小眾,新技術資料更少。為節(jié)省讀者時間,本書特別重視易讀性、易用性,具體有如下特點。
第一本中文OpenACC技術書籍,方便國內(nèi)讀者系統(tǒng)閱讀,快速掌握。
全面、準確:本書覆蓋OpenACC的所有特性,重要特性結合例子詳細講解,不常用的特性列出標準定義,方便查找。對特性、功能的描述均來自OpenACC規(guī)范,并用實例驗證,確保準確。
大量的例子:書中的示例代碼超過160個,不是代碼片斷,而是完整代碼,拿來即用。全部由筆者編寫、測試,運行無報錯。
兼顧C/C++和Fortran:以C/C++為主來講解,但所有的例子都有Fortran版的代碼,F(xiàn)ortran專用特性會詳細講解。物理、氣象等領域積累的優(yōu)秀Fortran代碼可以借此移植到新硬件上,重煥生機。
閱讀輕松:按照并行程序的編寫、調(diào)優(yōu)順序,先交代各階段面臨的問題,然后自然引入OpenACC提供的解決辦法,最后實測驗證效果。一切順理成章,讀者不會有云里霧里的感覺。
讀者對象科學家:迅速改造舊程序,快速編寫新的原型程序驗證算法、理論,將更多的時間投入到高價值的科研創(chuàng)新中去。
企業(yè)程序員:一套程序適配多種運行平臺,維護簡單;性能敏感的部分用CUDA等低層語言編寫,性能不敏感部分用OpenACC編寫,相互配合,兼得程序性能和開發(fā)效率。
本科生、研究生:花最少的時間掌握一門計算工具,省出時間學習更多的知識。
如何閱讀本書第1章介紹超級計算技術的發(fā)展趨勢和并行編程概況,可以從中了解OpenACC的作用。沒有CUDA C基礎的讀者能夠掌握基本概念,便于深入理解OpenACC的并行化技術。第2章介紹OpenACC語言的設計思路。第3~4章是本書的核心,將計算部分并行化,并將數(shù)據(jù)傳遞時間減到最少。至此,讀者已經(jīng)能夠編寫性能良好的OpenACC程序。第5~7章介紹高級并行技術,以進行極致性能優(yōu)化,以及與CUDA C/CUDA Fortran和各類庫的混合編程。第8章給出OpenACC規(guī)定的所有運行時例程,不用細讀,用到時再參考。第9章指導部署開發(fā)環(huán)境,以便快速上手。
勘誤和支持本人水平有限,錯誤與疏漏在所難免,懇請批評指正。聯(lián)系筆者請發(fā)送電子郵件至hpcfan@foxmail.com。更多技術資源請訪問www.gpujisuan.com。技術交流QQ群284876008(將滿)、564520462,歡迎加入。
致謝感謝國家并行計算機工程技術研究中心漆鋒濱老師撰寫第10章,并為本書作序。感謝PGI美女工程師王珍、帥氣工程師仰琎歆、Daniel Tian、資深專家Mathew Colgrove的技術支持。感謝機械工業(yè)出版社的策劃編輯高婧雅盡心協(xié)力。
序
前言
第1章 并行編程概覽1
1.1 加速器產(chǎn)品1
1.1.1 英偉達GPU3
1.1.2 英特爾至強融核處理器9
1.2 并行編程語言12
1.3 CUDA C14
1.3.1 線程組織方式16
1.3.2 運行過程18
1.3.3 內(nèi)存層級20
1.3.4 性能優(yōu)化技術21
第2章 OpenACC概覽22
2.1 OpenACC規(guī)范的內(nèi)容23
2.1.1 抽象加速器模型25
2.1.2 存儲模型25
2.1.3 計算執(zhí)行模型26
2.2 OpenACC 2.5規(guī)范29
第3章 OpenACC計算構件36
3.1 條件編譯37
3.2 導語格式38
3.3 計算構件kernels40
3.3.1 構件內(nèi)有1個循環(huán)41
3.3.2 構件內(nèi)2個循環(huán)44
3.3.3 構件內(nèi)二重嵌套循環(huán)45
3.3.4 kernels構件內(nèi)三重嵌套循環(huán)48
3.4 loop構件52
3.4.1 independent子語53
3.4.2 reduction歸約子語57
3.4.3 不常用的子語64
3.5 計算構件parallel66
3.5.1 gang單獨模式68
3.5.2 gang分裂模式70
3.5.3 二重循環(huán)73
3.5.4 三重循環(huán)75
3.6 組合導語77
3.7 案例研究:Jacobi迭代78
3.7.1 CPU上并行化84
3.7.2 GPU上并行化88
3.8 原子操作:atomic導語91
第4章 數(shù)據(jù)管理97
4.1 數(shù)據(jù)屬性、數(shù)據(jù)區(qū)域和數(shù)據(jù)生存期99
4.2 計算構件的伴隨數(shù)據(jù)區(qū)域100
4.2.1 引用計數(shù)101
4.2.2 present子語102
4.2.3 copy子語104
4.2.4 copyin子語105
4.2.5 copyout子語107
4.2.6 create子語108
4.2.7 數(shù)據(jù)子語內(nèi)的子數(shù)組111
4.2.8 private私有子語112
4.2.9 承上私有firstprivate子語115
4.2.10 帶有預置數(shù)據(jù)屬性的變量116
4.2.11 default默認子語117
4.2.12 案例研究:Jacobi迭代優(yōu)化數(shù)據(jù)傳輸117
4.3 data構件119
4.3.1 數(shù)據(jù)管理功能119
4.3.2 deviceptr子語121
4.3.3 案例研究:data構件迭代優(yōu)化Jacobi數(shù)據(jù)傳輸122
4.4 enter data導語和exit data導語128
4.4.1 C++類的數(shù)據(jù)生存期129
4.4.2 傳遞設備數(shù)據(jù)指針133
4.5 update導語135
4.6 declare導語138
4.6.1 device_resident子語139
4.6.2 create子語140
4.6.3 link子語140
4.6.4 用法舉例141
4.7 特定設備的子語146
第5章 計算區(qū)域內(nèi)的過程調(diào)用148
5.1 routine導語150
5.2 seq子語(C版)151
5.3 seq子語(Fortran版)152
5.4 routine(名字)154
5.5 bind子語155
5.6 用子語指定并行級別155
5.6.1 vector級別并行156
5.6.2 worker、worker級別并行159
5.7 計算圓周率π160
第6章 高級特性164
6.1 異步操作164
6.1.1 async子語165
6.1.2 wait子語165
6.1.3 wait導語166
6.2 設備計算與主機計算重疊166
6.3 設備上同時執(zhí)行多個隊列169
6.4 重疊計算與數(shù)據(jù)傳輸172
6.4.1 步驟0:串行代碼174
6.4.2 步驟1:計算并行化177
6.4.3 步驟2:分塊計算178
6.4.4 步驟3:數(shù)據(jù)分塊傳輸179
6.4.5 步驟4:重疊計算與傳輸181
6.5 雙向傳輸183
6.6 多個設備同時運算185
6.6.1 環(huán)境變量186
6.6.2 運行過程中選擇設備186
6.6.3 OpenMP調(diào)動多個設備195
第7章 與GPU生態(tài)環(huán)境互操作202
7.1 OpenACC調(diào)用CUDA C203
7.2 OpenACC調(diào)用CUDA Fortran205
7.3 CUDA C調(diào)用OpenACC207
7.4 捆綁主機地址與設備地址208
7.5 CUDA Fortran調(diào)用OpenACC210
7.6 OpenACC(C)調(diào)用cuBLAS211
7.7 OpenACC(Fortran)調(diào)用cuBLAS212
第8章 運行時函數(shù)213
8.1 運行時庫的定義213
8.2 運行時庫例程215
8.2.1 acc_get_num_devices215
8.2.2 acc_set_device_type216
8.2.3 acc_get_device_type217
8.2.4 acc_set_device_num217
8.2.5 acc_get_device_num218
8.2.6 acc_init218
8.2.7 acc_shutdown219
8.2.8 acc_async_test219
8.2.9 acc_async_test_all220
8.2.10 acc_wait220
8.2.11 acc_wait_async221
8.2.12 acc_wait_all221
8.2.13 acc_wait_all _async222
8.2.14 acc_get_default_async222
8.2.15 acc_set_default_async223
8.2.16 acc_on_device223
8.2.17 acc_malloc224
8.2.18 acc_free224
8.2.19 acc_copyin225
8.2.20 acc_create226
8.2.21 acc_copyout227
8.2.22 acc_delete228
8.2.23 acc_update_device229
8.2.24 acc_update_self230
8.2.25 acc_map_data231
8.2.26 acc_unmap_data231
8.2.27 acc_deviceptr231
8.2.28 acc_hostptr232
8.2.29 acc_is_present232
8.2.30 acc_memcpy_to_device233
8.2.31 acc_memcpy_from_device233
8.2.32 acc_memcpy_device234
第9章 開發(fā)環(huán)境搭建235
9.1 Windows 7236
9.2 Linux(rhel)244
9.3 編譯工具、特性支持度247
第10章 在神威·太湖之光上使用OpenACC253
10.1 SW26010眾核處理器253
10.2 存儲模型254
10.3 執(zhí)行模型256
10.4 數(shù)據(jù)管理256
附錄 著名超級計算機259
后記 碼農(nóng)的悲喜264
對于想要掌握OpenACC使用技巧和編程精髓的讀者來說,本書是一本非常具有參考價值的學習教程。與傳統(tǒng)的技術書籍相比,本書更加注重內(nèi)容的可讀性和易讀性,邏輯清晰,內(nèi)容全面準確,且更加注重編程實踐,有大量的C/C++/Fortran完整代碼實例,便于讀者學習和實踐。作為*一本中文的OpenACC技術書籍,可謂為國內(nèi)的編程學習者帶來了福音。
——漆鋒濱 CCF常務理事,國家并行計算機工程技術研究中心研究員