2013-02-24 66 views
1

我需要Cuda GLOBAL内存的一些帮助。在我的项目中,我必须声明全局数组,以避免在每次内核调用时发送此数组。内核调用示例之前的CUDA全局数组声明和初始化

编辑:

我的应用程序可以调用内核的1000倍以上,并在每一个电话我送他的大小比[1000×1000]以上的阵列,所以我认为这是花更多的时间,这就是为什么我的应用运行缓慢。所以,我需要声明的GPU全局数组,所以我的问题是

如何声明全局数组

如何内核调用前初始化从CPU全球阵列提前

谢谢

+1

共享内存只有块范围。在内核运行之前,您不能分配和填充共享内存。 – talonmies 2013-02-24 13:56:16

+0

也许我需要全球记忆?我可以为每个块,线程声明全局数组吗? – 2013-02-24 14:05:33

+0

是的,你可以,但它不能解决任何问题,请尝试将数据保存在全局内存中,并在调用内核时,将其复制到内核中的共享内存中。但如果您只使用一次数据或者只需要线程中的单个数据,则这样做不起作用。那么你最好使用一个普通变量并将其分配给它。这样编译器会自动将该变量转换为注册。 – 2013-02-24 15:30:28

回答

3

你编辑的问题很混乱,因为你说你要发送你的内核一个大小为1000 x 1000的数组,但是你想知道如何使用全局数组来做到这一点。我知道将这么多数据发送到内核的唯一方法是使用全局数组,因此您可能已经在全局内存中使用数组执行此操作。

尽管如此,有2种方法,至少,来创建和初始化在全局存储器阵列:

1.statically,使用__device__cudaMemcpyToSymbol,例如:

#define SIZE 100 
__device__ int A[SIZE]; 
... 
int main(){ 
    int myA[SIZE]; 
    for (int i=0; i< SIZE; i++) myA[i] = 5; 
    cudaMemcpyToSymbol(A, myA, SIZE*sizeof(int)); 
    ... 
    (kernel calls, etc.) 
} 

device variable referencecudaMemcpyToSymbol reference

2.dynamically,使用cudaMalloccudaMemcpy

#define SIZE 100 
... 
int main(){ 
    int myA[SIZE]; 
    int *A; 
    for (int i=0; i< SIZE; i++) myA[i] = 5; 
    cudaMalloc((void **)&A, SIZE*sizeof(int)); 
    cudaMemcpy(A, myA, SIZE*sizeof(int), cudaMemcpyHostToDevice); 
    ... 
    (kernel calls, etc.) 
} 

cudaMalloc referencecudaMemcpy reference

为清楚起见,我省略error checking,你应该对所有CUDA调用和内核调用做。

+0

太好了,谢谢:) – 2013-02-25 19:37:55

0

如果我很好地理解了这个问题,这个问题还不清楚,你想在全部内核调用中使用全局数组并将其发送到设备。这不好实践导致高延迟,因为在每个内核调用中,您需要将数据传输到设备。根据我的经验,这种做法导致负面加速。

最佳方式是使用我所说的触发器技术。你这样做的方式是:

  1. 声明设备中的两个数组。 d_arr1d_arr2
  2. 将数据host -> device复制到其中一个数组中。
  3. 作为内核参数传递指向d_arr1d_arr2
  4. 将数据处理到内核中。
  5. 在随之而来的内核调用你交换你逝去的指针作为参数

这样你可以避免传送数据的每个内核调用。您只能在主循环的开始和结束时进行传输。

int a, even =0; 
for(a=0;a<1000;a++) 
{ 
    if (even % 2 ==0) 
    //call to the kernel(pointer_a, pointer_b) 
    else 
    //call to the kernel(pointer_b, pointer_a) 
}