下面一段代碼
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。