簡體   English   中英

CUDA-塊和線程

[英]CUDA - Blocks and Threads

我已經在GPU上實現了字符串匹配算法。 與算法的順序版本相比,並行版本的搜索時間已大大減少,但是通過使用不同數量的塊和線程,我得到了不同的結果。 如何確定獲得最佳效果的塊數和數量?

我認為這個問題很難回答,即使不是不可能,因為它確實取決於算法及其運行方式。 由於我看不到您的實現,因此我可以給您一些線索:

  1. 不要使用全局內存,請檢查如何最大程度地利用共享內存。 通常可以很好地了解線程如何訪問內存以及如何檢索數據等。

  2. 了解您的經紗如何運作。 有時,如果線程和數據之間存在一對一的映射關系,那么扭曲中的線程可能會等待其他線程結束。 因此,您可以將線程映射到多個數據而不是一對一映射,以使它們保持忙碌狀態。

  3. 由於塊由在32個線程束中分組的線程組成,因此,最好的是,如果塊中的線程數是32的倍數,那么您就不會得到由3個線程等組成的線程束。

  4. 避免在變形中分散路徑。

希望對您有所幫助。

@Chris點也很重要,但更多地取決於算法本身。

  1. 有關內存查找的線程對齊,請參閱《 Cuda手冊》。 共享內存陣列的大小也應為16的倍數。

  2. 使用合並的全局內存讀取。 但是通過算法設計通常是這種情況,使用共享內存會有所幫助。

  3. 不要在全局內存中使用原子操作,也不要在可能的情況下使用原子操作。 他們很慢。 可以使用不同的技術來重寫某些使用原子運算的算法。

沒有顯示的代碼,沒有人會告訴您什么是最好的,或者為什么性能會發生變化。

每個內核塊的線程數是最重要的值。

計算該值的重要值為:

  • 每個多處理器的最大駐留線程數
  • 每個多處理器的最大駐留塊數
  • 每塊最大線程數
  • 每個多處理器的32位寄存器數

您的算法應可在所有GPU達到100%占用率的情況下進行擴展。 為此,我創建了一個幫助器類,該類將自動為使用的GPU檢測最佳線程號,並將其作為DEFINE傳遞給內核。

/**
 * Number of Threads in a Block
 *
 * Maximum number of resident blocks per multiprocessor : 8
 *
 * ///////////////////
 * Compute capability:
 * ///////////////////
 *
 * Cuda [1.0 - 1.1] =   
 *  Maximum number of resident threads per multiprocessor 768
 *  Optimal Usage: 768 / 8 = 96
 * Cuda [1.2 - 1.3] =
 *  Maximum number of resident threads per multiprocessor 1024
 *  Optimal Usage: 1024 / 8 = 128
 * Cuda [2.x] =
 *  Maximum number of resident threads per multiprocessor 1536
 *  Optimal Usage: 1536 / 8 = 192
 */ 
public static int BLOCK_SIZE_DEF = 96;

示例Cuda 1.1,每個SM達到786個駐留線程

  • 8個塊*每個塊96個線程= 786個線程
  • 3個塊*每個塊256個線程= 786個線程
  • 1個塊*每個塊512個線程= 512個線程<-33%的GPU將處於空閑狀態

書中也提到了這一點:

大規模並行處理器編程:動手方法(GPU計算系列的應用)

好的編程建議:

  1. 分析您的內核代碼並寫下它可以處理的最大線程數或可以處理的“單位”數。
  2. 還要輸出您的寄存器用法,並嘗試將其降低到相應的目標CUDA版本。 因為如果您在內核中使用太多寄存器,則會執行更少的塊,從而減少占用率和性能。
    示例:使用Cuda 1.1並使用每個SM最佳的768個駐留線程數,您可以使用8192個寄存器。 這導致每個線程/內核最多8192/768 = 10個最大寄存器。 如果您使用11,則GPU將減少1 Block,從而導致性能下降。

示例:我的獨立於矩陣的行向量歸一化內核。

/*
 * ////////////////////////
 * // Compute capability //
 * ////////////////////////
 *
 * Used 12 registers, 540+16 bytes smem, 36 bytes cmem[1]
 * Used 10 registers, 540+16 bytes smem, 36 bytes cmem[1] <-- with -maxregcount 10 Limit for Cuda 1.1
 * I:   Maximum number of Rows = max(x-dim)^max(dimGrid)
 * II:  Maximum number of Columns = unlimited, since they are loaded in a tile loop
 *
 * Cuda [1.0 - 1.3]: 
 * I:   65535^2 = 4.294.836.225
 *
 * Cuda [2.0]:
 * II:  65535^3 = 281.462.092.005.375
 */

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM