2012-08-25 130 views
0

非常有趣的行爲在Linux上使用CUDA 4.2和驅動程序295.41時,我目睹了一個非常有趣的行爲。 代碼本身是沒有什麼比找到一個隨機矩陣的最大值和標籤的位置更是1使用CUDA 4.2和驅動程序295.41

#include <stdio.h> 
#include <stdlib.h> 

const int MAX = 8; 

static __global__ void position(int* d, int len) { 
    int idx = threadIdx.x + blockIdx.x*blockDim.x; 
    if (idx < len) 
     d[idx] = (d[idx] == MAX) ? 1 : 0; 
} 

int main(int argc, const char** argv) { 
    int colNum = 16*512, rowNum = 1024; 
    int len = rowNum * colNum; 

    int* h = (int*)malloc(len*sizeof(int)); 
    int* d = NULL; 
    cudaMalloc((void**)&d, len*sizeof(int)); 

    // get a random matrix 
    for (int i = 0; i < len; i++) { 
     h[i] = rand()%(MAX+1); 
    } 

    // launch kernel 
    int threads = 128; 
    cudaMemcpy(d, h, len*sizeof(int), cudaMemcpyHostToDevice); 
    position<<<(len-1)/threads+1, threads>>>(d, len); 
    cudaMemcpy(h, d, len*sizeof(int), cudaMemcpyDeviceToHost); 

    cudaFree(d); 
    free(h); 
    return 0; 
} 

當我設置了這個rownum = 1024,代碼不工作的時候,就好像內核從未啓動。 如果rowNum = 1023,一切工作正常。

而這種的rowNum值以某種方式與塊的大小(在本例中,128)進行卷積,如果我改變塊大小爲512,則該行爲的rowNum = 4095和4096。

我之間發生不太確定這是一個錯誤還是我錯過了什麼?

回答

1

你應該總是調用CUDA函數後檢查錯誤。例如,在您的代碼中,內核啓動期間發生invalid configuration argument錯誤。

這通常意味着網格或塊的尺寸是無效的。

隨着colNum = 16*512, rowNum = 1024您試圖運行65536塊x 128線程,超過最大網格維度(對於具有計算能力1.x和2.x的GPU,對於65535塊,不確定約3.x)。

如果你需要運行更多的線程,你可以增加塊大小(你已經嘗試了它併產生了一些效果),或者使用2D/3D網格(3D僅適用於計算能力爲2.0或更高的設備) 。

+0

是的,你在這個特例中是正確的,但是,正如我之前提到的,即使我設置了rowNum = 4096,並且塊大小爲512,它也不起作用。 – user1624864

+0

@ user1624864有了這樣的配置(colNum = 16 * 512,rowNum = 4096,threads = 512),啓動配置是'65536 x 512',這也不應該工作 – aland

+0

好的,我明白了你的觀點。謝謝,大網格維度是行爲的原因。但是,我僅僅忽略了帖子中的所有錯誤檢查代碼,而不是生產中的代碼。因此,一般來說,SDK提供的「cuda安全調用」方法和驅動程序錯誤報告是否可靠一般會成爲問題? – user1624864