本書主要介紹了如何使用GPU和利用CUDAC語言對(duì)其進(jìn)行編程的。首先從基本的CUDA概念及結(jié)構(gòu)講起,一步一步地引導(dǎo)讀者進(jìn)入CUDA的內(nèi)部世界,由淺入深地介紹了其編程要求及其內(nèi)部架構(gòu),使讀者對(duì)其有了整體印象后,逐步深入了解其內(nèi)部機(jī)能,后介紹了GPU的一些專用函數(shù)和注意事項(xiàng)。
歡迎來到用CUDA C進(jìn)行異構(gòu)并行編程的奇妙世界!
現(xiàn)代的異構(gòu)系統(tǒng)正朝一個(gè)充滿無限計(jì)算可能性的未來發(fā)展。異構(gòu)計(jì)算正在不斷被應(yīng)用到新的計(jì)算領(lǐng)域—從科學(xué)到數(shù)據(jù)庫,再到機(jī)器學(xué)習(xí)的方方面面。編程的未來將是異構(gòu)并行編程的天下!
本書將引領(lǐng)你通過使用CUDA平臺(tái)、CUDA工具包和CUDA C語言快速上手GPU(圖形處理單元)計(jì)算。本書中設(shè)置的范例與練習(xí)也將帶你快速了解CUDA的專業(yè)知識(shí),助你早日達(dá)到專業(yè)水平!
本書寫給誰本書適用于任何想要利用GPU計(jì)算能力來提高應(yīng)用效率的人。它涵蓋了CUDA C編程領(lǐng)域最前沿的技術(shù),并有著以下突出的優(yōu)勢(shì):
風(fēng)格簡(jiǎn)潔描述透徹大量范例優(yōu)質(zhì)習(xí)題覆蓋面廣內(nèi)容聚焦高性能計(jì)算的需求如果你是一個(gè)經(jīng)驗(yàn)豐富的C程序員,并且想要通過學(xué)習(xí)CUDA C來提高高性能計(jì)算的專業(yè)才能,本書中建立在你現(xiàn)有知識(shí)之上的例題和習(xí)題,將使掌握CUDA C編程更加簡(jiǎn)單。僅需掌握一些C語言延伸的CUDA知識(shí),你便可以從大量的并行硬件中獲益。CUDA平臺(tái)、編程模型、工具和庫將使得異構(gòu)架構(gòu)編程變得簡(jiǎn)捷且高效。
如果你是計(jì)算機(jī)科學(xué)領(lǐng)域以外的專業(yè)人士,而且想要通過GPU上的并行編程來最大限度地提高工作效率,并提高應(yīng)用性能,那么本書正是為你量身打造的。書中的闡述清晰而簡(jiǎn)明,專人精心設(shè)計(jì)的示例,使用配置文件驅(qū)動(dòng)的方法,這些都將幫助你深入了解GPU編程并迅速掌握CUDA。
如果你是教授或任何學(xué)科的研究者,希望通過GPU計(jì)算推進(jìn)科學(xué)發(fā)現(xiàn)和創(chuàng)新,本書中將有你找到解決方案的捷徑。即使你沒有多少編程經(jīng)驗(yàn),在并行計(jì)算概念和計(jì)算機(jī)科學(xué)的知識(shí)方面也不夠精通,本書也可帶你快速入門異構(gòu)架構(gòu)并行編程。
如果你是C語言初學(xué)者并且有興趣探索異構(gòu)編程,本書也完全適合你,因?yàn)樗粡?qiáng)制要求讀者有豐富的C語言編程經(jīng)驗(yàn)。即使CUDA C和C語言使用相同的語法,二者的抽象概念和底層硬件也是全然不同的,因而對(duì)其中之一的經(jīng)驗(yàn)并不足以使你在學(xué)習(xí)另一個(gè)時(shí)感到輕松。所以,只要你對(duì)異構(gòu)編程有濃厚的興趣,只要你樂于學(xué)習(xí)新事物且樂于嘗試全新的思維方式,只要你對(duì)技術(shù)相關(guān)的話題有深入探索的熱情,本書也完全適合你。
即使你有不少關(guān)于CUDA C的經(jīng)驗(yàn),本書還是有助于知識(shí)更新、探索新工具以及了解最新CUDA功能。雖然本書旨在從零開始培養(yǎng)CUDA的專業(yè)人才,但它也含有許多先進(jìn)的CUDA概念、工具和框架的概述,它們將對(duì)CUDA開發(fā)人員大有裨益。
本書的內(nèi)容本書講解了CUDA C編程的基本概念與技術(shù),用于大幅加速應(yīng)用程序的性能,并包含了隨著CUDA工具包6.0和NVIDIA Kepler GPU一起發(fā)布的最新功能。在對(duì)從同質(zhì)架構(gòu)到異構(gòu)架構(gòu)的并行編程模式轉(zhuǎn)變進(jìn)行了簡(jiǎn)要介紹之后,本書將引導(dǎo)你學(xué)習(xí)必要的CUDA編程技能和最佳的練習(xí)實(shí)踐,包含但不僅限于CUDA編程模型、GPU執(zhí)行模型、GPU內(nèi)存模型、CUDA流和事件、多GPU編程的相關(guān)技術(shù)、CUDA感知MPI編程和NVIDIA開發(fā)工具。
本書采用一種獨(dú)特的方法來教授CUDA知識(shí),即將基礎(chǔ)性的概念講解與生動(dòng)形象的示例相結(jié)合,這些示例使用配置文件驅(qū)動(dòng)的方法來指導(dǎo)你實(shí)現(xiàn)最佳性能。我們對(duì)每一個(gè)主題都進(jìn)行了詳盡的講解,清晰地展示出了采用代碼示例形式詳細(xì)操作的過程。書中不僅教授如何使用基于CUDA的工具,還介紹了如何以抽象編程模型為基礎(chǔ)并憑借悟性與直覺對(duì)開發(fā)過程每一步驟的結(jié)果做出解釋,從而幫助你快速掌握CUDA的開發(fā)流程。
每章圍繞一個(gè)主題展開講解,運(yùn)用可行的代碼示例來演示GPU編程的基本功能和技術(shù),這之后就是我們精心設(shè)計(jì)的練習(xí),以便你進(jìn)一步探索加深理解。
所有的編程示例都是在裝有CUDA 5.0(或更高版本)和Kepler或Fermi GPU的Linux系統(tǒng)上運(yùn)行的。由于CUDA C是一種跨平臺(tái)的語言,因而書中的示例在其他平臺(tái)上也同樣適用,比如嵌入式系統(tǒng)、平板電腦、筆記本電腦、個(gè)人電腦、工作站以及高性能計(jì)算服務(wù)器。許多OEM供應(yīng)商支持各種類型的NVIDIA GPU。
本書的結(jié)構(gòu)本書共有10章,包含了以下主題。
第1章:基于CUDA的異構(gòu)并行計(jì)算本章首先簡(jiǎn)要介紹了使用GPU來完善CPU的異構(gòu)架構(gòu),以及向異構(gòu)并行編程進(jìn)行的模式轉(zhuǎn)變。
第2章:CUDA編程模型本章介紹了CUDA編程模型和CUDA程序的通用架構(gòu),從邏輯視角解釋了在CUDA中的大規(guī)模并行計(jì)算:通過編程模型直觀展示的兩層線程層次結(jié)構(gòu)。同時(shí)也探討了線程配置啟發(fā)性方法和它們對(duì)性能的影響。
第3章:CUDA執(zhí)行模型本章通過研究成千上萬的線程是如何在GPU中調(diào)度的,來探討硬件層面的內(nèi)核執(zhí)行問題。解釋了計(jì)算資源是如何在多粒度線程間分配的,也從硬件視角說明了它如何被用于指導(dǎo)內(nèi)核設(shè)計(jì),以及如何用配置文件驅(qū)動(dòng)方法來開發(fā)和優(yōu)化內(nèi)核程序。另外,本章還結(jié)合示例闡述了CUDA的動(dòng)態(tài)并行化和嵌套執(zhí)行。
第4章:全局內(nèi)存本章介紹了CUDA內(nèi)存模型,探討全局內(nèi)存數(shù)據(jù)布局,并分析了全局內(nèi)存的訪問模式。本章介紹了各種內(nèi)存訪問模式的性能表現(xiàn),闡述了統(tǒng)一內(nèi)存和CUDA 6.0中的新功能是如何簡(jiǎn)化CUDA編程的,以及如何提高程序員工作效率。
第5章:共享內(nèi)存和常量?jī)?nèi)存本章闡釋了共享內(nèi)存,即管理程序的低延遲緩存,是如何提高內(nèi)核性能的。它描述了共享內(nèi)存的優(yōu)化數(shù)據(jù)布
目 錄
譯者序
推薦序
自序
作者簡(jiǎn)介
技術(shù)審校者簡(jiǎn)介
前言
致謝
第1章 基于CUDA的異構(gòu)并行計(jì)算1
1.1 并行計(jì)算1
1.1.1 串行編程和并行編程2
1.1.2 并行性3
1.1.3 計(jì)算機(jī)架構(gòu)4
1.2 異構(gòu)計(jì)算6
1.2.1 異構(gòu)架構(gòu)7
1.2.2 異構(gòu)計(jì)算范例9
1.2.3 CUDA:一種異構(gòu)計(jì)算平臺(tái)10
1.3 用GPU輸出Hello World12
1.4 使用CUDA C編程難嗎15
1.5 總結(jié)16
1.6 習(xí)題16
第2章 CUDA編程模型18
2.1 CUDA編程模型概述18
2.1.1 CUDA編程結(jié)構(gòu)19
2.1.2 內(nèi)存管理20
2.1.3 線程管理24
2.1.4 啟動(dòng)一個(gè)CUDA核函數(shù)29
2.1.5 編寫核函數(shù)30
2.1.6 驗(yàn)證核函數(shù)31
2.1.7 處理錯(cuò)誤32
2.1.8 編譯和執(zhí)行32
2.2 給核函數(shù)計(jì)時(shí)35
2.2.1 用CPU計(jì)時(shí)器計(jì)時(shí)35
2.2.2 用nvprof工具計(jì)時(shí)39
2.3 組織并行線程40
2.3.1 使用塊和線程建立矩陣索引40
2.3.2 使用二維網(wǎng)格和二維塊對(duì)矩陣求和44
2.3.3 使用一維網(wǎng)格和一維塊對(duì)矩陣求和47
2.3.4 使用二維網(wǎng)格和一維塊對(duì)矩陣求和48
2.4 設(shè)備管理50
2.4.1 使用運(yùn)行時(shí)API查詢GPU信息50
2.4.2 確定最優(yōu)GPU53
2.4.3 使用nvidia-smi查詢GPU信息53
2.4.4 在運(yùn)行時(shí)設(shè)置設(shè)備54
2.5 總結(jié)54
2.6 習(xí)題55
第3章 CUDA執(zhí)行模型56
3.1 CUDA執(zhí)行模型概述56
3.1.1 GPU架構(gòu)概述57
3.1.2 Fermi架構(gòu)59
3.1.3 Kepler架構(gòu)61
3.1.4 配置文件驅(qū)動(dòng)優(yōu)化65
3.2 理解線程束執(zhí)行的本質(zhì)67
3.2.1 線程束和線程塊67
3.2.2 線程束分化69
3.2.3 資源分配74
3.2.4 延遲隱藏76
3.2.5 占用率78
3.2.6 同步81
3.2.7 可擴(kuò)展性82
3.3 并行性的表現(xiàn)83
3.3.1 用nvprof檢測(cè)活躍的線程束84
3.3.2 用nvprof檢測(cè)內(nèi)存操作85
3.3.3 增大并行性86
3.4 避免分支分化88
3.4.1 并行歸約問題88
3.4.2 并行歸約中的分化89
3.4.3 改善并行歸約的分化93
3.4.4 交錯(cuò)配對(duì)的歸約95
3.5 展開循環(huán)97
3.5.1 展開的歸約97
3.5.2 展開線程的歸約99
3.5.3 完全展開的歸約101
3.5.4 模板函數(shù)的歸約102
3.6 動(dòng)態(tài)并行104
3.6.1 嵌套執(zhí)行105
3.6.2 在GPU上嵌套Hello World106
3.6.3 嵌套歸約109
3.7 總結(jié)113
3.8 習(xí)題113
第4章 全局內(nèi)存115
4.1 CUDA內(nèi)存模型概述115
4.1.1 內(nèi)存層次結(jié)構(gòu)的優(yōu)點(diǎn)116
4.1.2 CUDA內(nèi)存模型117
4.2 內(nèi)存管理124
4.2.1 內(nèi)存分配和釋放124
4.2.2 內(nèi)存?zhèn)鬏?25
4.2.3 固定內(nèi)存127
4.2.4 零拷貝內(nèi)存128
4.2.5 統(tǒng)一虛擬尋址133
4.2.6 統(tǒng)一內(nèi)存尋址134
4.3 內(nèi)存訪問模式135
4.3.1 對(duì)齊與合并訪問135
4.3.2 全局內(nèi)存讀取137
4.3.3 全局內(nèi)存寫入145
4.3.4 結(jié)構(gòu)體數(shù)組與數(shù)組結(jié)構(gòu)體147
4.3.5 性能調(diào)整151
4.4 核函數(shù)可達(dá)到的帶寬154
4.4.1 內(nèi)存帶寬154
4.4.2 矩陣轉(zhuǎn)置問題155
4.5 使用統(tǒng)一內(nèi)存的矩陣加法167
4.6 總結(jié)171
4.7 習(xí)題172
第5章 共享內(nèi)存和常量?jī)?nèi)存174
5.1 CUDA共享內(nèi)存概述174
5.1.1 共享內(nèi)存175
5.1.2 共享內(nèi)存分配176
5.1.3 共享內(nèi)存存儲(chǔ)體和訪問模式176
5.1.4 配置共享內(nèi)存量181
5.1.5 同步183
5.2 共享內(nèi)存的數(shù)據(jù)布局185
5.2.1 方形共享內(nèi)存185
5.2.2 矩形共享內(nèi)存193
5.3 減少全局內(nèi)存訪問199
5.3.1 使用共享內(nèi)存的并行歸約199
5.3.2 使用展開的并行歸約202
5.3.3 使用動(dòng)態(tài)共享內(nèi)存的并行歸約204
5.3.4 有效帶寬205
5.4 合并的全局內(nèi)存訪問205
5.4.1 基準(zhǔn)轉(zhuǎn)置內(nèi)核205
5.4.2 使用共享內(nèi)存的矩陣轉(zhuǎn)置207
5.4.3 使用填充共享內(nèi)存的矩陣轉(zhuǎn)置210
5.4.4 使用展開的矩陣轉(zhuǎn)置211
5.4.5 增大并行性214
5.5 常量?jī)?nèi)存215
5.5.1 使用常量?jī)?nèi)存實(shí)現(xiàn)一維模板215
5.5.2 與只讀緩存的比較217
5.6 線程束洗牌指令219
5.6.1 線程束洗牌指令的不同形式220
5.6.2 線程束內(nèi)的共享數(shù)據(jù)222
5.6.3 使用線程束洗牌指令的并行歸約226
5.7 總結(jié)227
5.8 習(xí)題228
第6章 流和并發(fā)230
6.1 流和事件概述231
6.1.1 CUDA流231
6.1.2 流調(diào)度234
6.1.3 流的優(yōu)先級(jí)235
6.1.4 CUDA事件235
6.1.5 流同步237
6.2 并發(fā)內(nèi)核執(zhí)行240
6.2.1 非空流中的并發(fā)內(nèi)核240
6.2.2 Fermi GPU上的虛假依賴關(guān)系242
6.2.3 使用OpenMP的調(diào)度操作244
6.2.4 用環(huán)境變量調(diào)整流行為245
6.2.5 GPU資源的并發(fā)限制246
6.2.6 默認(rèn)流的阻塞行為247
6.2.7 創(chuàng)建流間依賴關(guān)系248
6.3 重疊內(nèi)核執(zhí)行和數(shù)據(jù)傳輸249
6.3.1 使用深度優(yōu)先調(diào)度重疊249
6.3.2 使用廣度優(yōu)先調(diào)度重疊252
6.4 重疊GPU和CPU執(zhí)行254
6.5 流回調(diào)255
6.6 總結(jié)256
6.7 習(xí)題257
第7章 調(diào)整指令級(jí)原語258
7.1 CUDA指令概述259
7.1.1 浮點(diǎn)指令259
7.1.2 內(nèi)部函數(shù)和標(biāo)準(zhǔn)函數(shù)261
7.1.3 原子操作指令262
7.2 程序優(yōu)化指令264
7.2.1 單精度與雙精度的比較264
7.2.2 標(biāo)準(zhǔn)函數(shù)與內(nèi)部函數(shù)的比較266
7.2.3 了解原子指令272
7.2.4 綜合范例277
7.3 總結(jié)279
7.4 習(xí)題280
第8章 GPU加速庫和OpenACC281
8.1 CUDA庫概述282
8.1.1 CUDA庫支持的作用域283
8.1.2 通用的CUDA庫工作流283
8.2 cuSPARSE庫285
8.2.1 cuSPARSE數(shù)據(jù)存儲(chǔ)格