内核调用前CUDA全局数组声明和初始化示例

内核调用前CUDA全局数组声明和初始化示例,cuda,declaration,shared-memory,Cuda,Declaration,Shared Memory,我需要一些关于Cuda全局内存的帮助。在我的项目中,我必须声明全局数组,以避免在每次内核调用时发送此数组 编辑: 我的应用程序可以调用内核1000次以上,每次调用时,我都会向他发送一个大于[1000 X 1000]的数组,因此我认为这需要更多的时间,这就是我的应用程序运行缓慢的原因。所以我需要为GPU声明全局数组,所以我的问题是 1如何声明全局数组 2如何在内核调用之前从CPU初始化全局数组 提前感谢您编辑的问题令人困惑,因为您说您正在向内核发送一个大小为1000 x 1000的数组,但您想知道

我需要一些关于Cuda全局内存的帮助。在我的项目中,我必须声明全局数组,以避免在每次内核调用时发送此数组

编辑:

我的应用程序可以调用内核1000次以上,每次调用时,我都会向他发送一个大于[1000 X 1000]的数组,因此我认为这需要更多的时间,这就是我的应用程序运行缓慢的原因。所以我需要为GPU声明全局数组,所以我的问题是

1如何声明全局数组

2如何在内核调用之前从CPU初始化全局数组


提前感谢

您编辑的问题令人困惑,因为您说您正在向内核发送一个大小为1000 x 1000的数组,但您想知道如何使用全局数组执行此操作。我所知道的将这么多数据发送到内核的唯一方法是使用全局数组,因此您可能已经在使用全局内存中的数组执行此操作了

不过,至少有两种方法可以在全局内存中创建和初始化数组:

1.静态地,使用
\uuuu设备
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.)
 }
(,)


为清楚起见,我省略了在所有cuda调用和内核调用中应该执行的操作。

如果我很好地理解这个问题(这有点不清楚),您希望在每次内核调用中使用全局数组并将其发送到设备。这种糟糕的做法会导致高延迟,因为在每次内核调用中,您都需要将数据传输到设备。根据我的经验,这种做法导致了负面的加速

最佳的方法是使用我称之为触发器的技术。您这样做的方式是:

  • 在设备中声明两个数组<代码>d_arr1和
    d_arr2
  • 将数据
    host->device
    复制到其中一个数组中
  • 作为内核参数指针传递到
    d_arr1
    d_arr2
  • 将数据处理到内核中
  • 在随后的内核调用中,交换作为参数传递的指针
  • 这样可以避免每次内核调用都传输数据。只能在主机循环的开始和结束时进行传输

    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)
    }
    
    int a,偶数=0;
    
    对于(a=0;共享内存只有块作用域。在内核运行之前,您无法分配和填充共享内存。可能我需要全局内存?我可以为每个块、线程声明全局数组吗?可以,但它不能解决任何问题,请尝试将数据保留在全局内存中,当您调用内核时,只需将其复制到内核中的共享内存中即可。但是如果你只使用了一次数据,或者你的线程中只需要一个数据,那么你最好使用一个普通变量并将该数据分配给它。这样编译器会自动将该变量转换为寄存器。非常感谢你的回复,你能看一下我的编辑吗?为什么我们必须手动对每个cuda调用执行错误检查;例如,为什么像
    cudamaloc()
    这样的函数还没有执行错误检查?
    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)
    }