並行計算之路——CUDA的軟件架構

入門和gpu相關知識。作爲開篇應該在完美不過了。
閱讀《CUDA專家手冊》第三章硬件架構後的一個筆記。之所以將目錄都打出來,因爲這就是CUDA的軟件架構。

軟件層

從應用程序本身到CUDA硬件上執行的CUDA驅動程序。
這裏寫圖片描述
驅動程序API和CUDA運行時中的函數名稱分別以cu*()和cuda*()大頭。3對尖括號<<<>>>爲啓用內核函數。

CUDA運行時和驅動程序

驅動程序版本可由cuDriverGetVersion()函數獲取。

驅動程序模型

  • 統一虛擬尋址
  • Windows顯式驅動模型
  • 超時檢測與恢復
  • 特斯拉計算集羣驅動程序

nvcc, PTX和微碼

  • nvcc是CUDA開發者使用的編譯器驅動程序。例如編譯、鏈接。
    這裏寫圖片描述
  • 並行線程執行(PTX, Parallel Thread eXecution)代碼是編譯後的GPU代碼的一種中間形式,它可以再次編譯爲原生的GPU微碼。

設備與初始化

設備數量

調用cuDeviceGetCount()或cudaGetDeviceCount()函數查詢範圍爲[0…DeviceCount - 1]的設備可用。

設備屬性

  • cuDeviceGetName()->查詢設備名稱
  • cuDeviceTotalMem()->查詢全局內存
  • cuDeviceComputeCapability()->查詢計算能力
  • cuDeviceAttribute()->查詢設備屬性
  • cudaGetDeviceProperties()->返回包括設備名稱和屬性信息的結構體cudaDeviceProp

無CUDA支持情況

CUDA運行時程序可以運行在不能運行CUDA的機器或未安裝CUDA的機器上。如果cudaGetDeviceCount()函數返回cudaSuccess和一個非0的設備數,CUDA是可以用的。

上下文

上下文類似CPU中的進程,管理CUDA程序中所有對象生命週期的容器,包括如下部分:

  • 所有內存分配(線性設備內存,主機內存,CUDA數組)
  • 模塊
  • CUDA流
  • CUDA事件
  • 紋理與表面引用
  • 使用本地內存的內核的設備內存
  • 進行調試、分析、同步操作時,所使用的內部資源
  • 換頁內存複製所使用的鎖定中轉緩衝區

cudaSetDevice()函數,爲調用的線程設置當前上下文。

生命週期與作用域

所有與CUDA上下文相關的分配資源都在上下文被銷燬的同時被銷燬。

資源預分配

少數情況下,CUDA不會預分配一個給定操作所需的全部資源。

地址空間

一組私有的虛擬內存地址,它可以分配線性設備內存或用以映射鎖頁主機內存。

當前上下文棧

三個主要功能。
- 單線程應用程序可以驅動多個GPU上下文
- 庫可以創建並管理它們自己上下文,而不需要干涉調用者的上下文。
- 庫不知曉調用它的CPU線程信息。
當前上下文棧的最初動機是使單線程CUDA應用程序可以驅動多個CUDA上下文。

上下文狀態

類似於CPU中的malloc()和printf()函數,cuCtxSetLimit()和cuCtxGetLimit()函數可以設置和獲取內核函數中對應函數的GPU空間上限。cuCtxSetCacheConfig()函數在啓動內核時指定所期望的緩存配置。

模塊與函數

模塊是代碼與一同加載的數據的集合,類似於windows中的動態鏈接庫(DLL)和Linux中的動態共享對象(DSO)。模塊只在CUDA驅動程序API中可用。
模塊被加載,應用程序就可以查詢其中包含的資源:
- 全局資源
- 函數(內核)
- 紋理引用

內核(函數)

在.cu文件中,用global標識內核。三對尖括號<<<>>>爲啓用內核函數。

設備內存

設備內存(或線性設備內存)駐留在CUDA地址空間上,可以被CUDA內核通過標準C/C++指針和數組解引用操作訪問。CUDA硬件並不支持請求式換頁,所以,所有的內存分配被真實的物理內存支持着。CUDA內存分配在物理內存耗盡時會失敗。

流與事件

【CUDA】cuda stream和event相關內容

流與事件使主機與設備之間的內存複製與內核操作可併發執行。
CUDA流被用來粗粒度管理多個處理單元的併發執行:

  • GPU/CPU
  • 在SM處理時可以執行DMA操作的複製引擎
  • 流處理器蔟(SM)
  • 併發內核
  • 併發執行的獨立GPU

流的操作是按順序執行的,像CPU的線程。

軟件流水線

軟件流水線解決因只有一個DMA引擎服務於GPU各種各樣的粗粒度硬件資源,應用軟件必須對多流中執行的操作進行流水操作。
開普勒架構減少了軟件流水線操作的需求,Hyper-Q技術實際上消除了流水線需求。

流回調

不懂。

NULL流

NULL流失GPU上所有引擎的集結地,所有的流內存複製函數都是異步的。NULL流最有用的場合是在不需要使用多流來利用GPU內部的併發性時,它可以解決應用程序的CPU/GPU併發。一旦流操作使用NULL流初始化,應用程序必須使用同步函數來確保操作在執行下一步之前完成。

事件

CUDA事件表示了另一個同步機制。同CUDA流一同引入,記錄CUDA事件是CUDA流中應用程序跟蹤進度的一個方式。當之前的所有CUDA流的操作執行結束後,全部的CUDA事件通過寫入一個共享同步內存位置而起作用。

主機內存

主機內存(CPU內存)。在所有運行CUDA的操作系統上,主機內存是虛擬化的。
爲了便利DMA,操作系統VMM(虛擬內存管理器)提供了一個頁面鎖定功能。被VMM標記爲鎖頁的內存就不能被換出,所以物理內存地址不能被修改。沒被鎖頁的內存稱作可換頁。

鎖頁主機內存

鎖頁主機內存由CUDA函數cuMemHostAlloc()/cudaHostAlloc()分配。該內存是頁鎖定的並且由當前CUDA上下文爲DMA設置。異步內存複製操作只在鎖頁內存上工作。
在CUDA中,鎖頁內存(pinned memory)是經過頁鎖定後且爲硬件訪問而映射後的主機內存,而頁面鎖定(page-locking)只是操作系統的一種不允許換頁的機制。但是在操作系統文檔中,這個兩個概念是同義的。

可分享的鎖頁內存

可分享頁內存在頁鎖定後映射給所有CUDA上下文。

映射鎖頁內存

映射鎖頁內存映射到CUDA上下文中的地址空間中,所以內核可能讀寫這塊內存。

主機內存註冊

用於開發者分配他們想要訪問的內存。

CUDA數組與紋理操作

紋理引用可以把輸入的任何座標轉化到設置的輸出格式,表面引用則暴露了一個常規的逐位操作接口來讀寫CUDA數組內容。

紋理引用

紋理引用是CUDA用來設置紋理硬件解釋實際內存內容的對象。

表面引用

表面引用可以是CUDA內核使用表面加載/存儲內建函數讀寫CUDA數組。

圖形互操作性

圖形互操作性函數族使得CUDA可以讀寫屬於OpenGL或Direct3D API的內存。

CUDA運行時與CUDA運動程序API

驅動程序API沒有提供任何性能優勢,但它爲應用程序提供了顯式的資源管理。

尾巴

草草結束該章內容,沒有實際的操作真得讓人很容易犯困。最後用一句話結束尾巴的內容——“當一位作家略去他所不知道的東西時,它們在作品中像漏洞似的顯示出來。”

參考:
《GPGPU編程技術——從GLSL、CUDA到OpenCL》♥♥♥♥♥
《數字圖像處理高級應用——基於MATLAB與CUDA的實現》♥♥♥
《基於CUDA的並行程序設計》♥♥♥
《CUDA專家手冊》♥♥♥♥♥
《高性能CUDA應用設計與開發》♥♥♥♥

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章