快速開發CUDA程序的方法

根據幾年的CUDA開發經驗,簡單的介紹下CUDA程序的大概開發步驟,按照先修改CPU串行程序後移植到GPU平臺的原理,把需要在GPU上做的工作儘量先在CPU平臺上修改,降低了程序的開發難度,同時有利用bug的調試。通過實現一種快速、有效地CUDA並行程序開發的方法,提高CUDA並行程序開發效率,降低CUDA並行程序開發週期和難度。

(1)    CPU串行程序分析

對於CPU串行程序,首先需要測試串行程序中的熱點函數,以及分析熱點函數的並行性:

a)       熱點測試

根據時間的測試結果確定熱點函數,作爲後面移植的重點代碼模塊。

b)       並行性分析

找出熱點代碼後,需要分析熱點部分的算法、數據特點,根據算法和數據的特點分析其是否可以並行,是否適合細粒度並行。

c)       確定CUDA內核使用的數組

根據對串行程序的分析,確定哪些模塊需要移植到GPU平臺上運行,對於需要運行上GPU平臺上的代碼內的數據進行分析,確定哪些數組需要在CUDA內核中使用,分析CUDA計算時,這些數組傳遞的方向是CPUtoGPU還是GPUtoCPU,以及每次傳遞時的數據大小等信息,然後設計這些數組的定義方式和大小。

(2)    仿CUDA格式的CPU串行程序

CUDA程序相對CPU程序比較複雜,當出現bug時,調試的難度也要比CPU程序大很多,爲了降低CUDA程序開發難度和週期,可以把一些GPU上的移植工作提前在CPU平臺上實現,具體涉及下面幾個方面:

a)       修改成可並行算法

對於CPU串行程序,有些代碼理論上可以並行,但經過CPU版本的優化之後導致代碼不能直接並行化,這時需要根據並行算法的要求修改原程序,改成可並行的模式;有些模塊理論上是可以並行的,但串行算法無法直接並行化,需要重新設計並行算法。

b)       數組修改

CPU串行程序中使用的數組定義的形式有可能無法在CUDA內核中直接使用,這時需要對數組的定義進行修改,如C語言程序,結構體中的指針需要改變成單獨的指針/數組,才能進行CPU與GPU之間的數據傳遞。另外,考慮到全局存儲器合併訪問的問題,有時還需要對數組的訪問方向進行修改,從而也需要改變數組的定義形式(如做行列變換)。總之,根據CUDA對數組使用和CPU串行程序之間的區別,提前把數組修改,方便程序的調試。

根據前面幾條的修改方式,對原CPU程序修改成一個仿CUDA格式的CPU串行程序,爲後面的移植工作做大量的準備,有利於後面CUDA程序的移植。

(3)    GPU數組設計、並行模型設計

GPU數組設計:設計GPU數組大小、類型、維度等信息;

設計CPU與GPU之間的數組通信方式;

並行模型設計:block和grid的設計滿足算法的數據特點。

(4)    CUDA並行程序基本版本

根據對原程序數組的分析,把CPU串行程序移植到GPU平臺,根據熱點模塊的算法和代碼實現CUDA內核代碼。

a)       設計調用語句

Kernel<<<grid, block, …>>>(…);

b)       設計CUDA內核

根據算法的並行性分析,設計內核,劃分每個線程的計算任務,利用同步語句滿足內核程序的邏輯正確性。

(5)    CUDA並行程序優化版本

根據步驟4實現的基本版本的CUDA並行程序,利用CUDA的優化技術進一步提高並行程序的性能,主要優化包括2個方面:通信優化和內核優化。

a)       CPU與GPU通信優化

GPU計算需要CPU與GPU之間進行數據的傳遞,合理的利用通信優化技術有利用提高GPU並行程序的性能,如流技術隱藏CPU與GPU的通信。

b)       CUDA內核優化

CUDA內核的優化對其性能更爲重要,主要涉及存儲器訪問優化和指令流優化,存儲器訪問優化包括:全局存儲器合併訪問,利用共享存儲器、常量存儲器、紋理存儲器替換全局存儲器的訪問,提高訪問速度;指令流優化是指利用高效的指令代替低效的指令,如CUDA中的快速函數。


以上方法只是大概介紹,難免有介紹的不全的地方,希望對大家的開發有點幫助。

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