教材:10710周志遠教授平行程式 https://www.youtube.com/playlist?list=PLS0SUwlYe8cxqw70UHOE5n4Lm-mXFXbZT 20250909 筆記 內容可能有錯僅供參考 17A 平行運算的CUDA 18A 平行記憶體 / GPU的架構 今日大綱 1.基本概念與 CPU-GPU 同步化 2.多 GPU 程式 3.GPU 之間資料傳輸的三種方式(同節點內) 4. 動態平行 (Dynamic Parallelism) ### 1.基本概念與 CPU-GPU 同步化 * **基礎部分的重要性**:理解 CUDA 的基本定義(如 **grid、block、thread**)以及它們如何映射到硬體架構上,對於理解 GPU 上的程式執行至關重要。 * **CPU 與 GPU 的同步化**: * **預設非同步執行**:CPU 與 GPU 之間預設是**非同步 (asynchronous)** 執行,各自獨立運行。 * **同步執行例外**:只有少數 CUDA 函數會涉及 host (CPU) 和 device (GPU) 共同完成,這些才是**同步 (synchronous)** 執行。最佳例子是 `cudaMemcpy`,特別是當資料在 device memory 和 host memory 之間傳輸時。 * **顯式同步**:可使用 `cuda event` 或 `cuda synchronization` 函數來強制同步 CPU 和 GPU 之間的執行。 * **序列化**:GPU 上所有待執行的事件或函數程式碼會被**序列化 (serialize)**,一個接一個執行。 ### 進階主題概覽 * **多 GPU (Multi-GPU) 程式**:處理 GPU 的限制(如記憶體大小),利用多個 GPU 裝置來運行程式。 * **動態平行 (Dynamic Parallelism)**:允許 GPU 上運行的 kernel 函數再啟動 (launch) 其他 kernel 函數。 ### 2.多 GPU 程式 多 GPU 程式主要分為兩大類:在同一個節點上使用多個 GPU,或跨不同節點使用多個 GPU。 1. **同節點上的多 GPU (Multi-GPU Node)** * **單一 CPU 執行緒控制多個 GPU**: * 方法:使用 `cudaSetDevice(deviceID)` 函數來指定接下來的 CUDA 函數應在哪個 GPU 上執行。 * **非同步特性**:因為幾乎所有 CUDA 函數都是非同步的,所以即使是單一執行緒輪流設置 `cudaSetDevice`,不同 GPU 上的計算仍可以**重疊 (overlap)** 執行,實現平行。 * **多個 CPU 執行緒控制多個 GPU**: * **常見做法**:這是一種更常見的做法,通常是一個 CPU 執行緒負責一個 GPU 裝置。 * **實現方式**:可透過 `Pthreads` 或 `OpenMP` 創建多個 CPU 執行緒,每個執行緒在其平行區域內啟動 CUDA kernel。 * **資源利用**:多個 CPU 執行緒可以同時在同一個 GPU 裝置上啟動 kernel。這些 kernel 可以同時執行,有助於充分利用 GPU 計算資源,避免浪費。 * **風險**:如果同時啟動的 kernel 所需資源總和超過 GPU 的承載能力,硬體排程器會介入,可能導致效能下降。 * **最佳化**:CPU 與 GPU 之間的綁定比例(如 1:1, 2:1, 3:1)會影響效能,需要進行調整。 * **例子**:OpenMP 搭配 `cudaSetDevice`,根據執行緒 ID 將工作分配到不同的 GPU 裝置。 2. **跨節點的多 GPU (Across Nodes)** * **使用 MPI**:通常透過 **MPI (Message Passing Interface)** 實現。每個 MPI Process 負責一個 GPU 裝置。 * **資料傳輸**:Process 之間的溝通是透過網路層進行。這代表資料可能需要先複製到 host 記憶體,再透過網路傳輸到另一台機器的 host 記憶體,導致較高的資料傳輸延遲。 * **現今趨勢**:許多 GPU 伺服器傾向於使用單一節點內的多 GPU,因為同節點內的 GPU 之間頻寬遠高於網路傳輸。 ### 3.GPU 之間資料傳輸的三種方式(同節點內) 在多 GPU 節點中,GPU 之間傳輸資料有三種主要方式: 1. **透過 Host 顯式複製 (Explicit Copy by Host)** * **概念**:資料從 GPU A 複製到 Host 記憶體,再從 Host 記憶體複製到 GPU B。 * **操作**:利用 `cudaSetDevice` 切換 GPU,並使用 `cudaMemcpy` 進行 device-to-host 和 host-to-device 的複製。 * **缺點**: * 需要兩次記憶體複製。 * 資料必須經過 host (CPU),效能受限於傳統 PCI-e 總線速度,即使有 NVLink 也無法加速此部分,因為它涉及 device-host-host-device 傳輸,而非 device-to-device。 2. **零複製 (Zero Copy)** * **概念**:資料只存放在 Host 記憶體中,GPU 透過記憶體映射 (memory mapping) 直接讀取 Host 記憶體,無需顯式複製。 * **機制**:GPU 的 device pointer 被映射到 Host 記憶體位址。為了讓 GPU 能直接存取,Host 記憶體必須被**釘住 (pinning/locking)**,防止作業系統進行分頁 (paging) 而改變其物理位址。 * **優點**: * 無需複製資料,可以處理非常大的資料集,因為資料不需佔用 device 記憶體。 * 實現了記憶體共享 (sharing) 的概念,一個 device 寫入的資料,其他 device 能夠即時看到。 * **缺點**: * 每次資料存取都必須回到 CPU (Host),跨越 PCI-e 總線,導致存取速度比 GPU 內部記憶體存取慢約 10 倍以上。 * 效能通常很差,不適合頻繁存取,但適用於存取次數極少且資料不會被重複使用的計算密集型程式。 * **Host 記憶體分配函數** (針對零複製和加速 `cudaMemcpy`): * `malloc`:標準 Host 記憶體分配,GPU 存取需透過 `cudaMemcpy`。 * `cudaMallocHost`:分配**已釘住 (pinned)** 的 Host 記憶體。GPU 可透過轉換後的 device pointer 直接存取。 * `cudaHostAlloc`:更靈活的 Host 記憶體分配函數,支援多個 flag 參數。 * `cudaHostAllocMapped` flag:確保分配的 Host 記憶體被釘住,效果同 `cudaMallocHost`。 * `cudaHostAllocPortable` flag:允許兩個或更多 GPU 映射到同一個 Host 記憶體空間,實現多 GPU 之間的零複製共享。 * **指標轉換**:Host pointer 必須透過 `cudaHostGetDevicePointer` 轉換為 GPU 可識別的 device pointer 才能在 kernel 中使用。 3. **點對點複製 (P2P Copy)** * **概念**:GPU 裝置之間的直接記憶體複製 (device-to-device copy),無需經過 Host。 * **函數**:使用 `cudaMemcpyPeer`。 * **優點**: * 繞過 Host (CPU),傳輸速度快,特別是當 GPU 之間有 **NVLink** 連接時,速度更快。 * `cudaMemcpyPeer` 可以是同步或非同步的。 * **操作**:直接提供來源和目的 GPU 的 device pointer,CUDA 驅動會負責複製。 * **建議**:這是最建議的 GPU 之間資料傳輸方式,因為它不需將資料搬移到 Host。 ### 4. 動態平行 (Dynamic Parallelism) * **概念**:允許在 GPU 上執行的 **kernel code 啟動 (launch) 其他 kernel code**。這意味著 kernel 可以遞歸地啟動新的 kernel,不需每次都回到 CPU。 * **要求**:需要 CUDA 5.0 或 compute capability 3.5 以上的硬體和函式庫版本。 * **目的**:**減少 CPU (host) 與 GPU (device) 之間的溝通開銷**。原本 CPU 需要多次啟動 kernel,現在只需啟動一個頂層 kernel,由它在 GPU 內部生成其他 kernel。 * **應用場景**: 1. **動態問題的負載平衡**:例如處理長度不一的矩陣 row/column。CPU 只需啟動處理第一維的 kernel,該 kernel 會根據實際長度在內部啟動更多子 kernel 進行計算,適應不同工作負載。 2. **遞歸細化與自適應視覺化**:在需要逐步放大或細化計算區域的應用中,kernel 可以根據需要遞歸地啟動子 kernel 進行更詳細的計算。 3. **減少 CPU 瓶頸**:在迭代型演算法(如 LU 分解)中,將整個迭代過程封裝在一個 kernel 函數中,由該 kernel 在 GPU 內部處理所有子任務的啟動和同步。這樣,CPU 只需與 GPU 溝通一次整個迭代,而非每次子任務都溝通,顯著減少溝通次數和 CPU 成為瓶頸的可能性。 4. **GPU 內部的函式庫程式碼**:複雜的計算可以被切分為函式庫程式碼,由一個 kernel 啟動多個 GPU 執行緒來加速這些函式庫的執行。 5. **遞迴演算法實現**:例如快速排序 (QuickSort) 等遞迴演算法,現在可以完全在 GPU 內部的 kernel 中實現,無需 CPU 介入。 * **總結**:動態平行使得程式設計更加直觀,特別是對於遞歸結構,同時透過減少 host-device 溝通,提升了整體系統效能。 --- 其他課程連結 [平行程式1C~2B Introduction parallel programming](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/Syxh3H7Kxe) [平行程式3A~3D The Latest Developments and Applications Using Parallel Programming](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJh7QFVKle) [平行程式4A~4B IO Parallel IO and Program Analysis](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJLMsuHFgg) [平行程式5A~5B The Latest Developments and Applications Using Parallel Programming](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/SJh57hIFle) [平行程式6A~6B Communication Routines and Parallel Function Code](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/r1X9kX_Fle) [平行程式 6C~6D Communication Routines and Parallel Function Code](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/S1DPjoYFlx) [平行程式 7A~8A Pthread:Synchronization Problem & Tools](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJu-_0tKge) [平行程式 8B~8D Synchronization Tools & Open Multi-Processing(OpenMP)](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/H1ki4E2Fee) [平行程式 9A~9B Synchronization Construct](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BJTYMrpKlx) [平行程式 10A~10B Synchronization Tools & Open Multi-Processing Synchronization Construct](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/B1cY6M1qee) [平行程式 10C~10D Synchronization Tools & Open Multi-Processing Synchronization Construct](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BkgFaNg5gg) [平行程式 11A~11B Parallel Work Pool and Termination / Parallel Sorting](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/H1hfOw-5xl) [平行程式 12A~12B Parallel Sorting and Pipelined Computations](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/Symo-zQ9eg) [平行程式 12C~12D Parallel Sorting and Pipelined Computations](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BJYNKDVceg) [平行程式 13A-13B Sychronous Parallelism](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HJ2UJ2Bqex) [平行程式 14A~14B Heterogeneous Computing](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BksS4yP5eg) [平行程式 14C~14D Heterogeneous Computing](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/BJrfTUd9xx) [平行程式 15A~15B Parallel Programming Model on GPU](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/ByWnl-t5gg) [平行程式 16A~16B What is Compute Unified Device Architecture(CUDA)?](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/HyYpsjcqgl) [平行程式 17A~18A 平行運算的CUDA](https://hackmd.io/@6FOC2dvARe-Vz0kVSyajew/H1dUeBT5lg) [平行程式 18B~19A 記憶體層級 / CUDA的優化](https://hackmd.io/@JuitingChen/HyF44e1jge) [平行程式 19B~19D 記憶體層級 / CUDA的優化 ](https://hackmd.io/@JuitingChen/ryPEu4lieg) [平行程式 20A~20B CUDA優化全域和區域記憶體/共享記憶體](https://hackmd.io/@JuitingChen/r1X659Zoxl) [平行程式 21A~21B Parallel Reduction / Distributed Computing Framework](https://hackmd.io/@JuitingChen/HyiOpozjxl) [平行程式 NTHU-PP-Chap10-Big Data-Part1 ](https://hackmd.io/@JuitingChen/Hyc-e3Golx) [平行程式 NTHU-PP-Chap10-Big Data-Part2 ](https://hackmd.io/@JuitingChen/ryC_QTXoxl) [平行程式 NTHU-PP-Chap11-MapReduce](https://hackmd.io/@JuitingChen/HJgBXJOsge) [平行程式 NTHU-PP-Chap12-Distributed Training-Part1](https://hackmd.io/@JuitingChen/ryh5hBtsge) [平行程式 NTHU-PP-Chap12-Distributed Training-Part2](https://hackmd.io/@JuitingChen/rJ2G7kdjxg) [平行程式 NTHU-PP-Chap12-Distributed Training-Part3](https://hackmd.io/@JuitingChen/HkA471dilx) [平行程式 NTHU-PP-Chap13-UCX-Part1](https://hackmd.io/@JuitingChen/rJbq103ieg) [平行程式 NTHU-PP-Chap13-UCX-Part2](https://hackmd.io/@JuitingChen/SJpNmk_ixl) [平行程式 NTHU-PP-Chap13-UCX-Part3](https://hackmd.io/@JuitingChen/HkIUYa13xe)