天天看點

《CUDA C程式設計權威指南》——2.3節組織并行線程

本節書摘來自華章社群《cuda c程式設計權威指南》一書中的第2章,第2.3節組織并行線程,作者[美] 馬克斯·格羅斯曼(max grossman) ,更多章節内容可以通路雲栖社群“華章社群”公衆号檢視

2.3 組織并行線程

從前面的例子可以看出,如果使用了合适的網格和塊大小來正确地組織線程,那麼可以對核心性能産生很大的影響。在向量加法的例子中,為了實作最佳性能我們調整了塊的大小,并基于塊大小和向量資料大小計算出了網格大小。

現在通過一個矩陣加法的例子來進一步說明這一點。對于矩陣運算,傳統的方法是在核心中使用一個包含二維網格與二維塊的布局來組織線程。但是,這種傳統的方法無法獲得最佳性能。在矩陣加法中使用以下布局将有助于了解更多關于網格和塊的啟發性的用法:

由二維線程塊構成的二維網格

由一維線程塊構成的一維網格

由一維線程塊構成的二維網格

2.3.1 使用塊和線程建立矩陣索引

通常情況下,一個矩陣用行優先的方法在全局記憶體中進行線性存儲。圖2-9所示的是一個8×6矩陣的小例子。

在一個矩陣加法核函數中,一個線程通常被配置設定一個資料元素來處理。首先要完成的任務是使用塊和線程索引從全局記憶體中通路指定的資料。通常情況下,對一個二維示例來說,需要管理3種索引:

《CUDA C程式設計權威指南》——2.3節組織并行線程

printthreadinfo函數被用于輸出關于每個線程的以下資訊:

線程索引

塊索引

矩陣坐标

線性全局記憶體偏移量

相應元素的值

用以下指令編譯并運作該程式:

《CUDA C程式設計權威指南》——2.3節組織并行線程
《CUDA C程式設計權威指南》——2.3節組織并行線程
《CUDA C程式設計權威指南》——2.3節組織并行線程

2.3.2 使用二維網格和二維塊對矩陣求和

在本節中,我們将使用一個二維網格和二維塊來編寫一個矩陣加法核函數。首先,應編寫一個校驗主函數以驗證矩陣加法核函數是否能得出正确的結果:

《CUDA C程式設計權威指南》——2.3節組織并行線程

然後,使用一個二維網格和二維塊按如下方法設定核函數的執行配置:

《CUDA C程式設計權威指南》——2.3節組織并行線程

接下來,調整塊的尺寸為32×16并重新編譯和運作該代碼。核函數的執行速度幾乎快了兩倍:

《CUDA C程式設計權威指南》——2.3節組織并行線程

你可能好奇為什麼隻是改變了執行配置,核心性能就幾乎翻了一倍。直覺地說,你可能會覺得這是因為第二次配置的線程塊數是第一次配置塊數的兩倍,是以并行性也是兩倍。你的直覺是正确的,但是,如果進一步減小塊的大小變為16×16,相比第一次配置你已經将塊的數量翻了四倍。如下所示,這種配置的結果比第一個好但是不如第二個。

表2-3總結了不同執行配置的性能。結果顯示,增加塊的數量不一定能提升核心性能。在第3章中,你将會學習到為什麼不同的執行配置會影響核函數的性能。

《CUDA C程式設計權威指南》——2.3節組織并行線程

由于在新的核函數中每個線程都要處理ny個元素,與使用二維網格和二維塊的矩陣求和的核函數相比,從線程和塊索引到全局線性記憶體索引的映射都将會有很大不同。由于在這個核函數啟動中使用了一個一維塊布局,是以隻有threadidx.x是有用的,并且使用核心中的一個循環來處理每個線程中的ny個元素。

一維網格和塊的配置如下:

《CUDA C程式設計權威指南》——2.3節組織并行線程

重新編譯并運作,可以看出核函數運作得更快了。

2.3.4 使用二維網格和一維塊對矩陣求和

當使用一個包含一維塊的二維網格時,每個線程都隻關注一個資料元素并且網格的第二個維數等于ny,如圖2-14所示。

這可以看作是含有一個二維塊的二維網格的特殊情況,其中塊的第二個維數是1。是以,從塊和線程索引到矩陣坐标的映射就變成:

《CUDA C程式設計權威指南》——2.3節組織并行線程
《CUDA C程式設計權威指南》——2.3節組織并行線程

從矩陣加法的例子中可以看出:

改變執行配置對核心性能有影響

傳統的核函數實作一般不能獲得最佳性能

對于一個給定的核函數,嘗試使用不同的網格和線程塊大小可以獲得更好的性能

在第3章,将會從硬體的角度學習産生這些問題的原因。

繼續閱讀