2014-03-19 101 views
0

這似乎是一個簡單的問題,但我無法在任何地方找到答案。 我有一個全球功能,我可以這樣調用:fnd一個__global__函數允許的最大塊數/線程數

func<<<nbBlocks,nbThreadByBlock, nbBytesOfSharedMmy>>>(args); 

如果我理解正確的話,我可從來沒有使用1024以上的nbThreadByBlock,但我怎麼能知道動態是什麼nbThreadByBlock最大也就是允許我的功能func和我的GPU?

我正確地認爲,如果我的func函數使用更多的局部變量,每個塊的最大線程數減少了嗎?

關於我可以使用的塊的總數,是否有上限?我在想,如果我把更多的東西放在可能的地方,他們將會被順序對待,這是真的嗎?

謝謝!

回答

1

下面一段代碼

cudaDeviceProp deviceProp; 
cudaGetDeviceProperties(&deviceProp, 0); //assuming current device ID is 0 

收集設備的性能進deviceProp。您可以看到here,在成功撥打cudaGetDeviceProperties後,您將可以訪問具有所需設備屬性的deviceProp成員。例如,deviceProp.maxThreadsPerMultiProcessor表示每多處理器的最大線程數,deviceProp.maxThreadsPerBlock表示每塊的最大線程數等

每塊與塊的整體數量的線程適當數量與您通話大多取決於您的設備屬性的功能和你的程序。您調用的每個塊都佔用SM的一部分。多少取決於您的塊請求的資源:線程,寄存器和共享內存。
考慮這個例子。假設您的設備SM最多可以有2048個線程,48 KB的共享內存和64 KB的寄存器。如果您的塊需要512個線程,並且同時使用SM可用的所有共享內存和寄存器,則不可能在SM中具有另一個具有相同特徵的塊。因此,如果不能使用2048減512個潛在SM線程,則可以將最大佔用率降低到25%。現在,如果您通過將塊中的線程數增加到1024來設計塊,則可以使用相同數量的寄存器和共享內存,將佔用率提高了一倍,達到50%。

通常不推薦使用大量的塊。 GPU將新塊安排到可用的SM中。如果所有的SM都被佔用,它將對該塊進行排隊,直到SM有足夠的空閒資源用於該塊。調度新塊對GPU有開銷(儘管很小)。在找到最佳塊大小之後,通過SM計算(或剖析)塊佔用率,然後調用盡可能多的塊,因爲它佔用了所有GPU SM。如果您需要更多的塊,您可以重用已完成作業的塊的線程。
例如轉換,其中

GPU_kernel<<<1024,512>>>(); 

__global__ void GPU_kernel(void){ 

    unsigned int tid = (blockIdx.x * blockDim.x) + threadIdx.x; 
    //rest of code 
} 

成其中

GPU_kernel<<<(number_of_SMs*number_of_blocks_per_SM),512>>>(); 

__global__ void GPU_kernel(void){ 

    unsigned int tid = (blockIdx.x * blockDim.x) + threadIdx.x; 
    for (; tid < 1024*512; tid += blockIdx.x* gridDim.x) { 
     //rest of code 
    } 
} 

通常導致更好的perfor曼斯。

另外請注意,在上述代碼片段中,我沒有包含適當的CUDA錯誤檢查。請運用您自己的方法來處理可能的錯誤。說明here