使用CUDA从GPU复制BIG数据

Yuc*_*ong 1 c c++ cuda

我是CUDA的新手,我正在尝试一个非常简单的任务 - 将内存复制到显卡然后复制回来.这是我编写的代码的简化版本.

const int arraySize = 100; 

int* data1 = NULL; 
int* data2 = NULL;
// Initialized both data1 and data2
// ... 

int* dev_data1 = NULL; 
int* dev_data2 = NULL; 
// Initialized both dev_data1 and dev_data2
// ... 

// copy data1 to device
cudaMemcpy(dev_data1, data1, arraySize*sizeof(int), cudaMemcpyHostToDevice );

// copy dev_data1 to dev_data2 with gpu
gpuCopy<<<1, arraySize>>>( dev_data1, dev_data2 ); 

// copy dev_data2 to data
cudaMemcpy(data2, dev_data2, arraySize*sizeof(int), cudaMemcpyDeviceToHost );
Run Code Online (Sandbox Code Playgroud)

并且gpuGopy是为以下几点:

__global__ void gpucopy( int* src, int* dst )
{
    int i = threadIdx.x;
    dst[i] = src[i];
} 
Run Code Online (Sandbox Code Playgroud)

我发现如果arraySize很小,上面的函数就可以了.但是如果arraySize达到特定大小,data2将变为全零.我的猜测是在运行gpu函数时存在某种限制.但有没有办法找到它?如果我有一个非常大的阵列,我怎么能把它复制到GPU(和后面)?

Rob*_*lla 5

首先,你应该做正确的cuda错误检查

其次,您可能会threadIdx.x给出一个全局唯一的线程ID.它不是.

所以修改你的内核行:

int i = threadIdx.x;
Run Code Online (Sandbox Code Playgroud)

至:

int i = blockIdx.x * blockDim.x + threadIdx.x;
Run Code Online (Sandbox Code Playgroud)

最后,每个块参数的线程数不能超过512或1024,具体取决于GPU.我们通过指定每个块的线程和每个网格的块参数来启动更大的网格:

#define nTPB 512
gpuCopy<<<(arraySize + nTPB - 1)/nTPB, nTPB>>>( dev_data1, dev_data2 ); 
Run Code Online (Sandbox Code Playgroud)

结合这种网格大小调整方法,我们通常在内核中包含一个线程检查,以防止对任意网格/问题大小的越界访问:

__global__ void gpucopy( int* src, int* dst, int size )
{
    int i = threadIdx.x + blockDim.x * blockIdx.x;
    if (i < size)
      dst[i] = src[i];
}
Run Code Online (Sandbox Code Playgroud)

同样我们必须告诉内核问题的大小:

gpuCopy<<<(arraySize + nTPB - 1)/nTPB, nTPB>>>( dev_data1, dev_data2, arraySize ); 
Run Code Online (Sandbox Code Playgroud)

您可能想查看CUDA编程指南