我是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(和后面)?
首先,你应该做正确的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编程指南