2013-02-23 53 views
0

我正在寫一個CUDA內核,我要在此設備上執行:CUDA最大數量管理

name: GeForce GTX 480 
CUDA capability: 2.0 
Total global mem: 1610285056 
Total constant Mem: 65536 
Shared mem per mp: 49152 
Registers per mp: 32768 
Threads in warp: 32 
Max threads per block: 1024 
Max thread dimensions: (1024, 1024, 64) 
Max grid dimensions: (65535, 65535, 65535) 

內核,以最小的形式,就是:

_global__ void CUDAvegas(...) 
{ 
devParameters p; 
extern __shared__ double shared[]; 
int width = Ndim * Nbins; 
int ltid = p.lId; 
while(ltid < 2* Ndim){ 
shared[ltid+2*width] = ltid; 
ltid += p.lOffset; //offset inside a block 
} 
__syncthreads(); 
din2Vec<double> lxp(Ndim, Nbins); 

__syncthreads(); 
for(int i=0; i< Ndim; i++){ 
    for(int j=0; j< Nbins; j++){ 
    lxp.v[i][j] = shared[i*Nbins+j]; 
    } 
} 
}// end kernel 

其中NDIM = 2,Nbins = 128,devParameters是一個類,其方法是p.lId用於計數本地線程的ID(一個塊內),和din2Cec是一類用於創建暗淡NDIM * Nbins的向量白衣新的命令(在它的析構函數中,我實現了相應的delete [])。 的NVCC輸出是:

nvcc -arch=sm_20 --ptxas-options=-v file.cu -o file.x 
ptxas info : Compiling entry function '_Z9CUDAvegas4LockidiiPdS0_S0_P7sumAccuP17curandStateXORWOWS0_i' for 'sm_20' 
ptxas info : Function properties for _Z9CUDAvegas4LockidiiPdS0_S0_P7sumAccuP17curandStateXORWOWS0_i 
       0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads 
ptxas info : Used 22 registers, 116 bytes cmem[0], 51200 bytes cmem[2] 

線程的數目與所述的多處理器限制兼容:最大共享存儲器,每個線程和MP最大值的寄存器和每MP翹曲。 如果我啓動64個線程×30塊(每塊共享內存是4128),它的所有權利,但如果使用超過30塊我得到錯誤:

cudaCheckError() failed at file.cu:508 : unspecified launch failure 
========= Invalid __global__ read of size 8 
=========  at 0x000015d0 in CUDAvegas 
=========  by thread (0,0,0) in block (1,0,0) 
=========  Address 0x200ffb428 is out of bounds 

我認爲這是在分配一個線程的問題內存,但我不明白什麼是我的限制每MP和總塊... 有人可以幫助我或提醒一個正確的話題?

PS:我知道提出什麼都不做的內核,但它只是瞭解我的極限問題。

+1

如果您希望幫助追蹤出界內存訪問,至少需要發佈完整的代碼。我們如何知道*在內核中的錯誤正在生成的位置,而沒有可以編譯和運行的行號或代碼? – talonmies 2013-02-23 17:21:17

回答

1

我認爲你收到的錯誤是解釋性的。需要指出的是,對於大小爲8的數據類型,存在超出範圍的全局讀取。超出邊界讀取的責任是塊(1,0,0)中的線程(0,0,0) 。我懷疑在最後嵌套的for循環中負責的指令是lxp.v[i][j] = shared[i*Nbins+j];。可能你分配的全局內存量與啓動塊的數量無關,所以當你啓動太多的塊時,你會收到這樣的錯誤。

+0

關於你對內存單線程分配量的懷疑,我認爲(但是請糾正我,如果我錯了),只要你分配太多的寄存器空間,編譯器就會開始將內存溢出到L1或全局內存。 – JackOLantern 2013-02-24 21:03:58

+0

謝謝你的回答,傑克! – 2013-02-28 15:30:44