2014-03-28 96 views
0

我正試圖在CUDA中實現一個小型項目。初始數據集包括:CUDA:存儲在全局內存中的地址

  • 陣列(pos)與地址(位置爲無符號整數)
  • 其具有基於
  • 存儲在所述第一陣列中的地址)將被訪問另一個陣列( data
  • 一個數組(res),它將包含某些計算的結果(對於這個例子,它只會在所有元素中寫入值1,以驗證數據一致性)。

下面的程序:

__global__ 
void testKernel (unsigned int *res, const unsigned int *data, unsigned int *pos) 
{ 
    int idx = blockIdx.x*blockDim.x + threadIdx.x; 
    int x = pos[idx]; 
    int foo = data[x];   // if I take out this line it works properly 
    res[idx] = 1; 
} 

res陣列(類似於存儲在data的那些)以書面奇怪值結束了,而不是1

調用看起來是這樣的:

#define WIDTH = 500 
#define BLK_SIZE = 64 
void main() { 
    int blockSize = BLK_SIZE; 
    int nBlocks = (WIDTH + BLK_SIZE - 1)/blockSize; 

    // memory allocations: res[WIDTH]; data[DATA_WIDTH]; pos[WIDTH] 
    // sanity checks for positions 
    // H2D memory transfers 
    testKernel <<<nBlocks,blockSize>>>(res_d, data_d, pos_d); 
    // D2H memory transfers 
    // free memory 
} 

現在我正在使用全局內存的一切,s因此我試圖達成最初的實施。內存分配,傳輸和內核調用都是正確的。

有沒有另一種方法來正確解決這個任務?如果是這樣,是什麼造成了奇怪的結果?

+0

你能否添加一對缺失的信息? 「WIDTH」值和內核調用行。和N_SAMPLES。 – Sigismondo

+0

我添加了請求的信息。 –

+0

我意識到代碼中有很多無用的信息。我會盡量減少問題,使它變得相關。 –

回答

0

因爲WIDTH是不是BLK_SIZE divisable你是否在你的代碼,排除插入一個徹頭徹尾的綁定的indeces:

__global__ 
void testKernel (unsigned int *res, const unsigned int *data, unsigned int *pos) 
{ 
    int idx = blockIdx.x*blockDim.x + threadIdx.x; 
    if (idx < WIDTH) { 
     ... 
    } 
} 

其實idx是從0到512在內核中,塊32(warp大小),獨立於你指定的blockDim(在這種情況下是多個,所以這不是問題)。

+0

是的,你是對的。一個典型的錯誤,它似乎不是一個有關存儲地址的問題。它試圖訪問未分配的數據位置。謝謝! –