2012-01-05 664 views
1

我有一個關於如何在cuda代碼中使用正確的變量的問題。我的程序有很多數組,它們需要在不同的函數中被訪問,我想避免傳遞它們,並且想要使用全局變量和2D mallocpitch數組,而不是扁平的一維數組。所以,我在想這樣的事情:cuda:爲設備內存使用全局變量

__device__ double * dataPtr ; 
__device__ size_t dataPitch; 
.... 
int main() 
{ 
double * dataPtrLoc; size_t dataPitchLoc; 
cudaMallocPitch((void**) &dataPtrLoc, &dataPitchLoc, width*sizeof(double), height); 
cudaMemcpyToSymbol(dataPtr, &dataPtrLoc, sizeof(dataPtrLoc)); 
cudaMemcpyToSymbol(dataPitch, &dataPitchLoc, sizeof(dataPitchLoc)); 
... 
} 

它看起來像是一個很好的方式來擁有全球2D設備數據嗎?你能提出建議嗎?

編輯:我在此程序並將其編譯和運行良好:

#include <stdio.h> 
__device__ int *d_gridPtr; 
__device__ size_t d_gridPitch; 

__device__ int valij(int ii, int jj) 
{ 
    int* row = (int*)((char*)d_gridPtr + ii * d_gridPitch); 
    return (row[jj]); 
} 

__global__ void printval() 
{ 
    int val0, val1, val2, val3; 
    val0= valij(0,0); 
    val1= valij(0,1); 
    val2= valij(1,0); 
    val3= valij(1,1); 
    printf("%d %d %d %d \n", val0, val1, val2, val3); 
} 

int main() 
{ 
    size_t d_gridPitchLoc; 
    int * d_gridPtrLoc; 
    cudaMallocPitch((void**)&d_gridPtrLoc, &d_gridPitchLoc, 2 * sizeof(int), 2); 
    cudaMemcpyToSymbol(d_gridPtr, & d_gridPtrLoc, sizeof(d_gridPtrLoc)); 
    cudaMemcpyToSymbol(d_gridPitch, &d_gridPitchLoc, sizeof(float)); 

    int h_mem[2*2]={0,1,100,4}; 
    size_t hostpitch = 2* sizeof(int); 
    cudaMemcpy2D(d_gridPtrLoc,d_gridPitchLoc,h_mem,hostpitch,2*sizeof(int),2,cudaMemcpyHostToDevice); 

    printval<<<1,1>>>(); 
    cudaDeviceReset(); 
} 
+1

該代碼不起作用 - 複製到dataPtr是錯誤的。但是不斷的記憶對於這類事情會更有意義。 – talonmies 2012-01-05 16:43:16

+1

無論數據是恆定的還是不相關的,您只是將指針存儲在常量內存中的全局內存數據中,而不是數據本身。無論如何,這就是內核參數如何在Fermi GPU中實現的。 – talonmies 2012-01-05 17:03:36

+0

我的數據不是恆定的。我記得讀到恆定內存不一定是恆定的,只是緩存全局內存(雖然不確定)。那麼,你是否仍然認爲,不斷的記憶會起作用? – user1118148 2012-01-05 17:03:41

回答

1

如果在同一時間的翹曲或塊訪問同一只讀全局存儲器地址(例如數組索引)的所有線程,然後考慮將該只讀全局數據存儲在一個__constant__存儲器陣列中。如果你寫數據,那麼你不能使用__constant__

如果是隻讀的陣列和您的訪問模式具有較強的2D局部性(經紗和/或塊內),可以考慮使用紋理代替。