-- 會員 / 註冊 --  
 帳號:
 密碼:
  | 註冊 | 忘記密碼
3/26 新書到! 3/19 新書到! 3/14 新書到! 12/12 新書到!
購書流程Q & A站務留言版客服信箱
3ds MaxMayaRhinoAfter EffectsSketchUpZBrushPainterUnity
PhotoShopAutoCadMasterCamSolidWorksCreoUGRevitNuke
C#CC++Java遊戲程式Linux嵌入式PLCFPGAMatlab
駭客資料庫搜索引擎影像處理FluentVR+ARANSYS深度學習
單晶片AVROpenGLArduinoRaspberry Pi電路設計CadenceProtel
HadoopPythonStm32CortexLabview手機程式AndroidiPhone
可查書名,作者,ISBN,3dwoo書號
詳細書籍分類

基于CUDA的GPU并行程序開發指南

( 簡體 字)
作者:[美]托爾加·索亞塔(Tolga Soyata) 著類別:1. -> 程式設計 -> 綜合
譯者:
出版社:機械工業出版社基于CUDA的GPU并行程序開發指南 3dWoo書號: 51451
詢問書籍請說出此書號!

缺書
NT售價: 895

出版日:7/1/2019
頁數:425
光碟數:0
站長推薦:
印刷:黑白印刷語系: ( 簡體 版 )
加入購物車 加到我的最愛
(請先登入會員)
ISBN:9787111630616
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證)
作者序:

譯者序:

前言:

我經歷過在IBM大型機上編寫匯編語言來開發高性能程序的日子。用穿孔卡片編寫程序,編譯需要一天時間;你要留下在穿孔卡片上編寫的程序,第二天再來拿結果。如果出現錯誤,你需要重復這些操作。在那些日子里,一位優秀的程序員必須理解底層的機器硬件才能編寫出好的代碼。當我看到現在的計算機科學專業的學生只學習抽象層次較高的內容以及像Ruby這樣的語言時,我總會感到有些焦慮。盡管抽象是一件好事,因為它可以避免由于不必要的細節而使程序開發陷入困境,但當你嘗試開發高性能代碼時,抽象就變成了一件壞事。

自第一個CPU出現以來,計算機架構師在CPU硬件中添加了令人難以置信的功能來“容忍”糟糕的編程技巧。20年前,你必須手動設置機器指令的執行順序,而如今在硬件中CPU會為你做這些(例如,亂序執行)。在GPU世界中也能清晰地看到類似的趨勢。由于GPU架構師正在改進硬件功能,5年前我們在GPU編程中學習的大多數性能提升技術(例如,線程發散、共享存儲體沖突以及減少原子操作的使用)正變得與改進的GPU架構越來越不相關,甚至5∼10年后,即使是一名非常馬虎的程序員,這些因素也會變得無關緊要。當然,這只是一個猜測。GPU架構師可以做的事取決于晶體管總數及客戶需求。當說晶體管總數時,是指GPU制造商可以將多少個晶體管封裝到集成電路(IC)即“芯片”中。當說客戶需求時,是指即使GPU架構師能夠實現某個功能,但如果客戶使用的應用程序不能從中受益,就意味著浪費了部分的晶體管數量。

從編寫教科書的角度出發,我考慮了所有的因素,逐漸明確講授GPU編程的最佳方式是說明不同系列GPU(如Fermi、Kepler、Maxwell和Pascal)之間的不同并指明發展趨勢,這可以讓讀者準備好迎接即將到來的下一代GPU,再下一代,……我會重點強調那些相對來說會長期存在的概念,同時也關注那些與平臺相關的概念。也就是說,GPU編程完全關乎性能,如果你了解程序運行的平臺架構,編寫出了與平臺相關的代碼,就可以獲得更高的性能。所以,提供平臺相關的解釋與通用的GPU概念一樣有價值。本書內容的設計方式是,越靠后的章節,內容越具有平臺特定性。

我認為本書最獨特的地方就是通過第一部分中的CPU多線程來解釋并行。第二部分介紹了GPU的大規模并行(與CPU的并行不同)。由于第一部分解釋了CPU并行的方式,因此讀者在第二部分中可以較為容易地理解GPU的并行。在過去的6年中,我設計了這種方法來講授GPU編程,認識到從未學過并行編程課程的學生并不是很清楚大規模并行的概念。與GPU相比,“并行化任務”的概念在CPU架構中更容易理解。

本書的組織如下。第一部分(第1章至第5章)使用一些簡單的程序來演示如何將大任務分成多個并行的子任務并將它們映射到CPU線程,分析了同一任務的多種并行實現方式,并根據計算核心和存儲單元操作來研究這些方法的優缺點。本書的第二部分(第6章至第11章)將同一個程序在多個Nvidia GPU平臺(Fermi、Kepler、Maxwell和Pascal)上并行化,并進行性能分析。由于CPU和GPU的核心和內存結構不同,分析結果的差異有時很有趣,有時與直覺相反。本書指出了這些結果的不同之處,并討論了如何讓GPU代碼運行得更快。本書的最終目標是讓程序員了解所有的做法,這樣他們就可以應用好的做法,并避免將不好的做法應用到項目中。

盡管第一部分和第二部分已經完全涵蓋了編寫一個好的CUDA程序需要的所有內容,但總會有更多需要了解的東西。本書的第三部分為希望拓寬視野的讀者指明了方向。第三部分并不是相關主題的詳細參考文檔,只是給出了一些入門介紹,讀者可以從中獲得學習這些內容的動力。這部分主要介紹了一些流行的CUDA庫,比如cuBLAS、cuFFT、Nvidia Performance Primitives和Thrust(第12章);OpenCL編程語言(第13章);使用其他編程語言和API庫進行GPU編程,包括Python、Metal、Swift、OpenGL、OpenGL ES、OpenCV和微軟HLSL(第14章);深度學習庫cuDNN(第15章)。




Tolga Soyata
內容簡介:

本書旨在幫助讀者了解與基于CUDA的GPU并行編程技術有關的基本概念,并掌握使用C語言進行GPU高性能編程的相關技巧。本書共分為三部分,第一部分通過CPU多線程編程解釋了并行計算,使得沒有太多并行計算基礎的讀者也能毫無阻礙地入門CUDA;第二部分重點介紹了基于CUDA的GPU大規模并行程序的開發與實現,并通過大量的性能分析幫助讀者理解如何開發一個好的GPU并行程序以及GPU架構對程序性能的影響;第三部分介紹了一些常用的CUDA庫、OpenCL編程語言、其他GPU編程語言和API以及深度學習庫cuDNN。

本書內容翔實、實例豐富,可作為高等院校相關專業高年級本科生和研究生課程的教材,也可作為計算機相關技術人員的參考書。



本書詳細介紹GPU編程方法,展示了不同的GPU系列之間的區別。這樣的講授方式能使讀者更好地應對下一代或未來的GPU系列。本書重點關注基礎性概念,同時也關注與平臺相關的概念。提供平臺相關的內容與通用的GPU概念一樣有價值。

本書分為三個部分,第一部分利用CPU的多線程概念介紹了并行性的基礎知識,通過一些簡單的代碼示例展示了如何將一個大任務分成若干并行的子任務,然后將它們映射到CPU線程。對于同一個任務,嘗試了多種不同的并行實現方法,并針對核心和內存操作分析了這些方法的優缺點。

第二部分介紹了GPU的大規模并行性。在多個Nvidia GPU平臺上對相同的程序進行了并行化實現,并分析了它們的性能。由于CPU和GPU的核心與內存結構不同,運行結果也顯示出了很多有趣的差異。最終目標是希望程序員既能掌握有益的思想,也能了解那些不好的做法,這樣在自己開發的程序中能采用有用的策略,同時避免犯錯。

第三部分為想要拓展知識的讀者提供了建議。該部分簡要介紹了一些常用的CUDA庫(例如cuBLAS、cuFFT、NPP和Thrust),OpenCL編程語言,其他GPU編程語言和API(如Python、OpenCV、OpenGL、Swift與Metal),以及深度學習庫cuDNN。
目錄:

譯者序
前言
關于作者
第一部分 理解CPU的并行性
第1章 CPU并行編程概述 2
1.1 并行編程的演化 2
1.2 核心越多,并行性越高 3
1.3 核心與線程 4
1.3.1 并行化更多的是線程還是核心 5
1.3.2 核心資源共享的影響 6
1.3.3 內存資源共享的影響 6
1.4 第一個串行程序 7
1.4.1  理解數據傳輸速度 8
1.4.2 imflip.c中的main( )函數 9
1.4.3 垂直翻轉行:FlipImageV( ) 10
1.4.4 水平翻轉列:FlipImageH( ) 11
1.5 程序的編輯、編譯、運行 12
1.5.1 選擇編輯器和編譯器 12
1.5.2 在Windows 7、8、10平臺上開發 12
1.5.3 在Mac平臺上開發 14
1.5.4 在Unix平臺上開發 14
1.6 Unix速成 15
1.6.1 與目錄相關的Unix命令 15
1.6.2 與文件相關的Unix命令 16
1.7 調試程序 19
1.7.1 gdb 19
1.7.2 古典調試方法 20
1.7.3 valgrind 22
1.8 第一個串行程序的性能 22
1.8.1 可以估計執行時間嗎 23
1.8.2 代碼執行時OS在做什么 23
1.8.3 如何并行化 24
1.8.4 關于資源的思考 25
第2章 開發第一個CPU并行程序 26
2.1 第一個并行程序 26
2.1.1 imflipP.c中的main( )函數 27
2.1.2 運行時間 28
2.1.3 imflipP.c中main( )函數代碼的劃分 28
2.1.4 線程初始化 30
2.1.5 創建線程 31
2.1.6  線程啟動/執行 32
2.1.7 線程終止(合并) 33
2.1.8 線程任務和數據劃分 34
2.2 位圖文件 35
2.2.1 BMP是一種無損/不壓縮的文件格式 35
2.2.2 BMP圖像文件格式 36
2.2.3 頭文件ImageStuff.h 37
2.2.4 ImageStuff.c中的圖像操作函數 38
2.3 執行線程任務 40
2.3.1 啟動線程 41
2.3.2 多線程垂直翻轉函數MTFlipV( ) 43
2.3.3 FlipImageV( )和MTFlipV( )的比較 46
2.3.4 多線程水平翻轉函數MTFlipH(?) 47
2.4 多線程代碼的測試/計時 49
第3章 改進第一個CPU并行程序 51
3.1 程序員對性能的影響 51
3.2 CPU對性能的影響 52
3.2.1 按序核心與亂序核心 53
3.2.2 瘦線程與胖線程 55
3.3 imf?lipP的性能 55
3.4 操作系統對性能的影響 56
3.4.1 創建線程 57
3.4.2 線程啟動和執行 57
3.4.3 線程狀態 58
3.4.4 將軟件線程映射到硬件線程 59
3.4.5  程序性能與啟動的線程 60
3.5 改進imf?lipP 61
3.5.1  分析MTFlipH( )中的內存訪問模式 62
3.5.2  MTFlipH( )的多線程內存訪問 63
3.5.3  DRAM訪問的規則 64
3.6 imf?lipPM:遵循DRAM的規則 65
3.6.1 imflipP的混亂內存訪問模式 65
3.6.2 改進imflipP的內存訪問模式 65
3.6.3 MTFlipHM( ):內存友好的MTFlipH( ) 66
3.6.4 MTFlipVM( ):內存友好的MTFlipV( ) 69
3.7 imflipPM.C的性能 69
3.7.1 imflipP.c和imflipPM.c的性能比較 70
3.7.2 速度提升:MTFlipV( )與MTFlipVM( ) 71
3.7.3 速度提升:MTFlipH( )與MTFlipHM( ) 71
3.7.4 理解加速:MTFlipH( )與MTFlipHM( ) 71
3.8 進程內存映像 72
3.9 英特爾MIC架構:Xeon Phi 74
3.10 GPU是怎樣的 75
3.11 本章小結 76
第4章 理解核心和內存 77
4.1 曾經的英特爾 77
4.2 CPU和內存制造商 78
4.3 動態存儲器與靜態存儲器 79
4.3.1 靜態隨機存取存儲器(SRAM) 79
4.3.2  動態隨機存取存儲器(DRAM) 79
4.3.3 DRAM接口標準 79
4.3.4 DRAM對程序性能的影響 80
4.3.5 SRAM對程序性能的影響 81
4.4 圖像旋轉程序:imrotate.c 81
4.4.1 imrotate.c的說明 82
4.4.2 imrotate.c:參數限制和簡化 82
4.4.3 imrotate.c:實現原理 83
4.5 imrotate的性能 87
4.5.1 線程效率的定性分析 87
4.5.2 定量分析:定義線程效率 87
4.6 計算機的體系結構 89
4.6.1 核心、L1$和L2$ 89
4.6.2 核心內部資源 90
4.6.3  共享L3高速緩存(L3 $) 91
4.6.4 內存控制器 92
4.6.5 主存 92
4.6.6 隊列、非核心和I/O 93
4.7 imrotateMC:讓imrotate更高效 94
4.7.1 Rotate2( ):平方根和浮點除法有多差 96
4.7.2 Rotate3( )和Rotate4( ):sin( )和cos( )有多差 97
4.7.3 Rotate5( ):整數除法/乘法有多差 98
4.7.4 Rotate6( ):合并計算 100
4.7.5 Rotate7( ):合并更多計算 100
4.7.6 imrotateMC的總體性能 101
4.8 本章小結 103
第5章 線程管理和同步 104
5.1 邊緣檢測程序:imedge.c 104
5.1.1 imedge.c的說明 105
5.1.2 imedge.c:參數限制和簡化 106
5.1.3 imedge.c:實現原理 106
5.2 imedge.c:實現 108
5.2.1 初始化和時間戳 109
5.2.2 不同圖像表示的初始化函數 110
5.2.3 啟動和終止線程 111
5.2.4 高斯濾波 112
5.2.5 Sobel 113
5.2.6 閾值過濾 114
5.3 imedge的性能 115
5.4 imedgeMC:讓imedge更高效 116
5.4.1 利用預計算降低帶寬 116
5.4.2 存儲預計算的像素值 117
5.4.3 預計算像素值 118
5.4.4 讀取圖像并預計算像素值 119
5.4.5 PrGaussianFilter 120
5.4.6 PrSobel 121
5.4.7 PrThreshold 121
5.5 imedgeMC的性能 122
5.6 imedgeMCT:高效的線程同步 123
5.6.1 屏障同步 124
5.6.2 用于數據共享的MUTEX結構 125
5.7 imedgeMCT:實現 127
5.7.1 使用MUTEX:讀取圖像、預計算 128
5.7.2 一次預計算一行 130
5.8 imedgeMCT的性能 131
第二部分 基于CUDA的GPU編程
第6章 GPU并行性和CUDA概述 134
6.1 曾經的Nvidia 134
6.1.1 GPU的誕生 134
6.1.2 早期的GPU架構 136
6.1.3 GPGPU的誕生 137
6.1.4 Nvidia、ATI Technologies和Intel 138
6.2 統一計算設備架構 140
6.2.1 CUDA、OpenCL和其他GPU語言 140
6.2.2 設備端與主機端代碼 140
6.3 理解GPU并行 141
6.3.1 GPU如何實現高性能 142
6.3.2 CPU與GPU架構的差異 143
6.4 圖像翻轉的CUDA版:imflipG.cu 144
6.4.1 imflipG.cu:將圖像讀入CPU端數組 146
6.4.2 初始化和查詢GPU 147
6.4.3 GPU端的時間戳 148
6.4.4 GPU端內存分配 152
6.4.5 GPU驅動程序和Nvidia運行時引擎 153
6.4.6 CPU到GPU的數據傳輸 153
6.4.7 用封裝函數進行錯誤報告 154
6.4.8 GPU核函數的執行 155
6.4.9 完成GPU核函數的執行 157
6.4.10 將GPU結果傳回CPU 158
6.4.11 完成時間戳 158
6.4.12 輸出結果和清理 158
6.4.13 讀取和輸出BMP文件 159
6.4.14  Vflip( ):垂直翻轉的GPU核函數 160
6.4.15 什么是線程ID、塊ID和塊維度 163
6.4.16 Hflip( ):水平翻轉的GPU核函數 165
6.4.17 硬件參數:threadIDx.x、blockIdx.x和blockDim.x 165
6.4.18 PixCopy( ):復制圖像的GPU核函數 165
6.4.19 CUDA關鍵字 166
6.5 Windows中的CUDA程序開發 167
6.5.1 安裝MS Visual Studio 2015和CUDA Toolkit 8.0 167
6.5.2 在Visual Studio 2015中創建項目imflipG.cu 168
6.5.3 在Visual Studio 2015中編譯項目imflipG.cu 170
6.5.4 運行第一個CUDA應用程序:imflipG.exe 173
6.5.5 確保程序的正確性 174
6.6 Mac平臺上的CUDA程序開發 175
6.6.1 在Mac上安裝XCode 175
6.6.2 安裝CUDA驅動程序和CUDA工具包 176
6.6.3 在Mac上編譯和運行CUDA應用程序 177
6.7 Unix平臺上的CUDA程序開發 177
6.7.1 安裝Eclipse和CUDA工具包 177
6.7.2 使用ssh登錄一個集群 178
6.7.3 編譯和執行CUDA代碼 179
第7章 CUDA主機/設備編程模型 181
7.1 設計程序的并行性 181
7.1.1 任務的并行化 182
7.1.2 什么是Vflip( )的最佳塊尺寸 183
7.1.3 imflipG.cu:程序輸出的解釋 183
7.1.4 imflipG.cu:線程塊和圖像的大小對性能的影響 184
7.2 核函數的啟動 185
7.2.1 網格 185
7.2.2 線程塊 187
7.2.3 線程 187
7.2.4 線程束和通道 189
7.3 imf?lipG.cu:理解核函數的細節 189
7.3.1 在main( )中啟動核函數并將參數傳遞給它們 189
7.3.2 線程執行步驟 190
7.3.3 Vflip( )核函數 191
7.3.4 Vflip( )和MTFlipV( )的比較 192
7.3.5 Hflip( )核函數 194
7.3.6 PixCopy( )核函數 194
7.4 PCIe速度與CPU的關系 196
7.5 PCIe總線對性能的影響 196
7.5.1 數據傳輸時間、速度、延遲、吞吐量和帶寬 196
7.5.2 imflipG.cu的PCIe吞吐量 197
7.6 全局內存總線對性能的影響 200
7.7 計算能力對性能的影響 203
7.7.1 Fermi、Kepler、Maxwell、Pascal和Volta系列 203
7.7.2 不同系列實現的相對帶寬 204
7.7.3 imflipG2.cu:計算能力2.0版本的imflipG.cu 205
7.7.4 imflipG2.cu:main( )的修改 206
7.7.5 核函數PxCC20( ) 208
7.7.6 核函數VfCC20( ) 208
7.8 imflipG2.cu的性能 210
7.9 古典的CUDA調試方法 212
7.9.1 常見的CUDA錯誤 212
7.9.2 return調試法 214
7.9.3 基于注釋的調試 216
7.9.4 printf(?)調試 216
7.10 軟件錯誤的生物學原因 217
7.10.1 大腦如何參與編寫/調試代碼 218
7.10.2 當我們疲倦時是否會寫出錯誤代碼 219
第8章 理解GPU的硬件架構 221
8.1 GPU硬件架構 222
8.2 GPU硬件的部件 222
8.2.1 SM:流處理器 222
8.2.2 GPU核心 223
8.2.3 千兆線程調度器 223
8.2.4 內存控制器 225
8.2.5 共享高速緩存(L2$) 225
8.2.6 主機接口 225
8.3 Nvidia GPU架構 226
8.3.1 Fermi架構 227
8.3.2 GT、GTX和計算加速器 227
8.3.3 Kepler架構 228
8.3.4 Maxwell架構 228
8.3.5 Pascal架構和NVLink 229
8.4 CUDA邊緣檢測:imedgeG.cu 229
8.4.1 CPU和GPU內存中存儲圖像的變量 229
8.4.2 為GPU變量分配內存 231
8.4.3 調用核函數并對其進行計時 233
8.4.4 計算核函數的性能 234
8.4.5 計算核函數的數據移動量 235
8.4.6 輸出核函數性能 236
8.5 imedgeG:核函數 237
8.5.1 BWKernel( ) 237
8.5.2 GaussKernel( ) 239
8.5.3 SobelKernel( ) 240
8.5.4 ThresholdKernel( ) 242
8.6 imedgeG.cu的性能 243
8.6.1 imedgeG.cu:PCIe總線利用率 244
8.6.2 imedgeG.cu:運行時間 245
8.6.3 imedgeG.cu:核函數性能比較 247
8.7 GPU代碼:編譯時間 248
8.7.1 設計CUDA代碼 248
8.7.2 編譯CUDA代碼 250
8.7.3 GPU匯編:PTX、CUBIN 250
8.8 GPU代碼:啟動 250
8.8.1 操作系統的參與和CUDA DLL文件 250
8.8.2 GPU圖形驅動 251
8.8.3 CPU與GPU之間的內存傳輸 251
8.9 GPU代碼:執行(運行時間) 252
8.9.1 獲取數據 252
8.9.2 獲取代碼和參數 252
8.9.3 啟動線程塊網格 252
8.9.4 千兆線程調度器(GTS) 253
8.9.5 線程塊調度 254
8.9.6 線程塊的執行 255
8.9.7 透明的可擴展性 256
第9章 理解GPU核心 257
9.1 GPU的架構系列 258
9.1.1 Fermi架構 258
9.1.2 Fermi SM的結構 259
9.1.3 Kepler架構 260
9.1.4 Kepler SMX的結構 260
9.1.5 Maxwell架構 261
9.1.6 Maxwell SMM的結構 262
9.1.7 Pascal GP100架構 264
9.1.8 Pascal GP100 SM的結構 265
9.1.9 系列比較:峰值GFLOPS和峰值DGFLOPS 266
9.1.10 GPU睿頻 267
9.1.11 GPU功耗 268
9.1.12 計算機電源 268
9.2 流處理器的構建模塊 269
9.2.1 GPU核心 269
9.2.2 雙精度單元(DPU) 270
9.2.3 特殊功能單元(SFU) 270
9.2.4 寄存器文件(RF) 270
9.2.5 讀取/存儲隊列(LDST) 271
9.2.6 L1$和紋理高速緩存 272
9.2.7 共享內存 272
9.2.8 常量高速緩存 272
9.2.9 指令高速緩存 272
9.2.10 指令緩沖區 272
9.2.11 線程束調度器 272
9.2.12 分發單元 273
9.3 并行線程執行(PTX)的數據類型 273
9.3.1 INT8:8位整數 274
9.3.2 INT16:16位整數 274
9.3.3 24位整數 275
9.3.4 INT32:32位整數 275
9.3.5 判定寄存器(32位) 275
9.3.6 INT64:64位整數 276
9.3.7 128位整數 276
9.3.8 FP32:單精度浮點(float) 277
9.3.9 FP64:雙精度浮點(double) 277
9.3.10 FP16:半精度浮點(half) 278
9.3.11 什么是FLOP 278
9.3.12 融合乘法累加(FMA)與乘加(MAD) 278
9.3.13 四倍和八倍精度浮點 279
9.3.14 Pascal GP104引擎的SM結構 279
9.4 imflipGC.cu:核心友好的imflipG 280
9.4.1 Hflip2( ):預計算核函數參數 282
9.4.2 Vflip2( ):預計算核函數參數 284
9.4.3 使用線程計算圖像坐標 285
9.4.4 線程塊ID與圖像的行映射 285
9.4.5 Hflip3( ):使用二維啟動網格 286
9.4.6 Vflip3( ):使用二維啟動網格 287
9.4.7 Hflip4( ):計算2個連續的像素 288
9.4.8 Vflip4( ):計算2個連續的像素 289
9.4.9 Hflip5( ):計算4個連續的像素 290
9.4.10 Vflip5( ):計算4個連續的像素 291
9.4.11 PixCopy2( )、PixCopy3( ):一次分別復制2個和4個連續的像素 292
9.5 imedgeGC.cu:核心友好的imedgeG 293
9.5.1 BWKernel2( ):使用預計算的值和2D塊 293
9.5.2 GaussKernel2( ):使用預計算的值和2D塊 294
第10章 理解GPU內存 296
10.1 全局內存 297
10.2 L2高速緩存 297
10.3 紋理/L1高速緩存 298
10.4 共享內存 298
10.4.1 分拆與專用共享內存 299
10.4.2 每核心可用的內存資源 299
10.4.3 使用共享內存作為軟件高速緩存 300
10.4.4 分配SM中的共享內存 300
10.5 指令高速緩存 300
10.6 常量內存 301
10.7 imflipGCM.cu:核心和內存友好的imflipG 301
10.7.1 Hflip6( )、Vflip6( ):使用共享內存作為緩沖區 301
10.7.2 Hflip7( ):共享內存中連續的交換操作 303
10.7.3 Hflip8( ):使用寄存器交換4個像素 305
10.7.4 Vflip7( ):一次復制4個字節(int) 307
10.7.5 對齊與未對齊的內存數據訪問 308
10.7.6 Vflip8( ):一次復制8個字節 308
10.7.7 Vflip9( ):僅使用全局內存,一次復制8個字節 309
10.7.8 PixCopy4( )、PixCopy5( ):使用共享內存復制1個和4個字節 310
10.7.9 PixCopy6( )、PixCopy7( ):使用全局內存復制1個和2個整數 311
10.8 imedgeGCM.cu:核心和內存友好的imedgeG 312
10.8.1 BWKernel3( ):使用字節操作來提取RGB 312
10.8.2 GaussKernel3( ):使用常量內存 314
10.8.3 處理常量的方法 315
10.8.4 GaussKernel4( ):在共享內存中緩沖1個像素的鄰居 316
10.8.5 GaussKernel5( ):在共享內存中緩沖4個像素的鄰居 318
10.8.6 GaussKernel6( ):將5個垂直像素讀入共享內存 320
10.8.7 GaussKernel7( ):去除邊界像素的影響 322
10.8.8 GaussKernel8( ):計算8個垂直像素 324
10.9 CUDA占用率計算器 326
10.9.1 選擇最佳的線程/塊 327
10.9.2 SM級資源限制 328
10.9.3 什么是占用率 329
10.9.4 CUDA占用率計算器:資源計算 330
10.9.5 案例分析:GaussKernel7(?) 334
10.9.6 案例分析:GaussKernel8(?) 337
第11章 CUDA流 340
11.1 什么是流水線 342
11.1.1 重疊執行 342
11.1.2 暴露與合并的運行時間 343
11.2 內存分配 344
11.2.1 物理與虛擬內存 345
11.2.2 物理地址到虛擬地址的轉換 345
11.2.3 固定內存 345
11.2.4 使用cudaMallocHost( )分配固定內存 346
11.3 CPU與GPU之間快速的數據傳輸 346
11.3.1 同步數據傳輸 346
11.3.2 異步數據傳輸 347
11.4 CUDA流的原理 347
11.4.1 CPU到GPU的傳輸、核函數的執行、GPU到CPU的傳輸 347
11.4.2 在CUDA中實現流 348
11.4.3 復制引擎 348
11.4.4 核函數執行引擎 349
11.4.5 并發的上行和下行PCIe傳輸 349
11.4.6 創建CUDA流 350
11.4.7 銷毀CUDA流 350
11.4.8 同步CUDA流 350
11.5 imGStr.cu:流式圖像處理 351
11.5.1 將圖像讀入固定內存 351
11.5.2 同步與單個流 353
11.5.3 多個流 354
11.5.4 多流之間的數據依賴 356
11.6 流式水平翻轉核函數 360
11.7 imGStr.cu:流式邊緣檢測 362
11.8 性能對比:imGStr.cu 365
11.8.1 同步與異步結果 366
11.8.2 結果的隨機性 366
11.8.3 隊列優化 366
11.8.4 最佳流式結果 367
11.8.5 最差流式結果 369
11.9 Nvidia可視化分析器:nvvp 370
11.9.1 安裝nvvp和nvprof 370
11.9.2 使用nvvp 370
11.9.3 使用nvprof 371
11.9.4 imGStr的同步和單流結果 372
11.9.5 imGStr的2流和4流結果 373
第三部分 拓展知識
第12章 CUDA庫 376
12.1 cuBLAS 377
12.1.1 BLAS級別 377
12.1.2 cuBLAS數據類型 377
12.1.3 安裝cuBLAS 378
12.1.4 變量聲明和初始化 378
12.1.5 設備內存分配 379
12.1.6 創建上下文 379
12.1.7 將數據傳輸到設備端 379
12.1.8 調用cuBLAS函數 380
12.1.9 將數據傳回主機 380
12.1.10 釋放內存 381
12.1.11 cuBLAS程序示例:矩陣的標量操作 381
12.2 cuFFT 382
12.2.1 cuFFT庫特征 383
12.2.2 復數到復數變換示例 383
12.2.3 實數到復數變換示例 384
12.3 Nvidia性能庫(NPP) 384
12.4 Thrust庫 386
第13章 OpenCL簡介 388
13.1 什么是OpenCL 388
13.1.1 多平臺 388
13.1.2 基于隊列 389
13.2 圖像翻轉核函數 389
13.3 運行核函數 390
13.3.1 選擇設備 390
13.3.2 運行核函數 392
13.3.3 OpenCL程序的運行時間 396
13.4 OpenCL中的邊緣檢測 396
第14章 其他GPU編程語言 402
14.1 使用Python進行GPU編程 402
14.1.1 imflip的PyOpenCL版本 403
14.1.2 PyOpenCL的逐元素核函數 406
14.2 OpenGL 408
14.3 OpenGL ES:用于嵌入式系統的OpenGL 409
14.4 Vulkan 409
14.5 微軟的高級著色語言 409
14.5.1 著色 410
14.5.2 HLSL 410
14.6 Apple的Metal API 411
14.7 Apple的Swift編程語言 411
14.8 OpenCV 411
14.8.1 安裝OpenCV和人臉識別 411
14.8.2 移動–微云–云實時人臉識別 412
14.8.3 加速即服務(AXaas) 412
第15章 深度學習中的CUDA 413
15.1 人工神經網絡 413
15.1.1 神經元 413
15.1.2 激活函數 414
15.2 全連接神經網絡 415
15.3 深度網絡/卷積神經網絡 415
15.4 訓練網絡 416
15.5 cuDNN深度學習庫 416
15.5.1 創建一個層 417
15.5.2 創建一個網絡 418
15.5.3 前向傳播 418
15.5.4 反向傳播 419
15.5.5 在網絡中使用cuBLAS 419
15.6 Keras 419
參考文獻 421
術語表 424
序: