C++ 使用CUDA在GPU之间复制大数据
我是CUDA的新手,我自己正在尝试一项非常简单的任务——将内存复制到图形卡,然后再复制回来。下面是我编写的代码的简化版本 常数int arraySize=100; int*data1=NULL; int*data2=NULL; //初始化了数据1和数据2 // ... int*dev_data1=NULL; int*dev_data2=NULL; //初始化了dev_数据1和dev_数据2 // ... //将数据1复制到设备 cudaMemcpydev_data1,data1,arraySize*sizeofint,cudamemcpyhostto设备; //使用gpu将dev_数据1复制到dev_数据2 gpuCopy开发数据1、开发数据2; //将dev_data2复制到数据 cudaMemcpydata2,开发数据2,阵列化*sizeofint,cudaMemcpyDeviceToHost; gpuGopy如下所示: __全局无效gpucopy int*src,int*dst { int i=threadIdx.x; dst[i]=src[i]; }C++ 使用CUDA在GPU之间复制大数据,c++,c,cuda,C++,C,Cuda,我是CUDA的新手,我自己正在尝试一项非常简单的任务——将内存复制到图形卡,然后再复制回来。下面是我编写的代码的简化版本 常数int arraySize=100; int*data1=NULL; int*data2=NULL; //初始化了数据1和数据2 // ... int*dev_data1=NULL; int*dev_data2=NULL; //初始化了dev_数据1和dev_数据2 // ... //将数据1复制到设备 cudaMemcpydev_data1,data1,arrayS
我发现如果arraySize很小,上面的函数就可以工作。但如果arraySize达到特定大小,data2将变为全零。我的猜测是,在运行gpu功能时存在某种限制。但有办法找到答案吗?如果我有一个非常大的阵列,我如何将它复制到GPU并返回 首先你应该做的是 其次,您可能会觉得threadIdx.x提供了一个全局唯一的线程ID,但事实并非如此 因此,从以下位置修改内核行:
int i = threadIdx.x;
致:
最后,根据GPU,每个块的线程数参数不能超过512或1024。我们通过指定“每个块的线程数”和“每个网格的块数”参数来启动更大的网格:
#define nTPB 512
gpuCopy<<<(arraySize + nTPB - 1)/nTPB, nTPB>>>( dev_data1, dev_data2 );
结合这种网格大小调整方法,我们通常在内核中包含线程检查,以防止对任意网格/问题大小的越界访问:
__global__ void gpucopy( int* src, int* dst, int size )
{
int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < size)
dst[i] = src[i];
}
同样,我们必须告诉内核问题的大小:
gpuCopy<<<(arraySize + nTPB - 1)/nTPB, nTPB>>>( dev_data1, dev_data2, arraySize );
您可能想首先回顾一下您应该做的事情 其次,您可能会觉得threadIdx.x提供了一个全局唯一的线程ID,但事实并非如此 因此,从以下位置修改内核行:
int i = threadIdx.x;
致:
最后,根据GPU,每个块的线程数参数不能超过512或1024。我们通过指定“每个块的线程数”和“每个网格的块数”参数来启动更大的网格:
#define nTPB 512
gpuCopy<<<(arraySize + nTPB - 1)/nTPB, nTPB>>>( dev_data1, dev_data2 );
结合这种网格大小调整方法,我们通常在内核中包含线程检查,以防止对任意网格/问题大小的越界访问:
__global__ void gpucopy( int* src, int* dst, int size )
{
int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < size)
dst[i] = src[i];
}
同样,我们必须告诉内核问题的大小:
gpuCopy<<<(arraySize + nTPB - 1)/nTPB, nTPB>>>( dev_data1, dev_data2, arraySize );
您可能需要查看threadIdx索引取决于体系结构,不能随意设置
以下代码在我的系统上一直工作到arraySize==1024,但在arraySize==1025时,我得到了未定义的值
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
using namespace std;
__global__ void gpucopy( int* src, int* dst )
{
int i = threadIdx.x;
dst[i] = src[i];
}
int main()
{
const int arraySize = 500; // >= 1025 will fail on my system!
int* data1 = new int[arraySize];
int* data2 = new int[arraySize];
// Initialized both data1 and data2
// ...
for(int i=0; i<arraySize; i++)
data1[i] = 2*i;
int* dev_data1 = NULL;
int* dev_data2 = NULL;
// Initialized both dev_data1 and dev_data2
// ...
cudaMalloc(&dev_data1, arraySize*sizeof(int));
cudaMalloc(&dev_data2, arraySize*sizeof(int));
// 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 );
for(int i=0; i<arraySize; i++)
if(data2[i] != data1[i])
cout << "Error: data is different - data2[" << i << "] is " << data2[i] << endl;
return 0;
}
您可以通过查看文档或使用deviceQuery函数找到该值
threadIdx索引依赖于体系结构,您不能随意设置它
以下代码在我的系统上一直工作到arraySize==1024,但在arraySize==1025时,我得到了未定义的值
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
using namespace std;
__global__ void gpucopy( int* src, int* dst )
{
int i = threadIdx.x;
dst[i] = src[i];
}
int main()
{
const int arraySize = 500; // >= 1025 will fail on my system!
int* data1 = new int[arraySize];
int* data2 = new int[arraySize];
// Initialized both data1 and data2
// ...
for(int i=0; i<arraySize; i++)
data1[i] = 2*i;
int* dev_data1 = NULL;
int* dev_data2 = NULL;
// Initialized both dev_data1 and dev_data2
// ...
cudaMalloc(&dev_data1, arraySize*sizeof(int));
cudaMalloc(&dev_data2, arraySize*sizeof(int));
// 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 );
for(int i=0; i<arraySize; i++)
if(data2[i] != data1[i])
cout << "Error: data is different - data2[" << i << "] is " << data2[i] << endl;
return 0;
}
您可以通过查看文档或使用deviceQuery函数找到该值
请发布完整的可编译样本!对于您发布的代码片段,它不可能帮助您解决有关0的问题。另外,请您知道具体尺寸有多大?@maxywb。刚刚在我的机器上测试过。具体尺寸为512。但是根据下面的答案,这个数字应该在不同的机器上有所不同。发布的代码可能会出现内核启动故障,导致arraySize在513及以上或1025及以上的版本没有修改输出,具体取决于传递的特定GPU和编译命令。请发布完整的可编译示例!对于您发布的代码片段,它不可能帮助您解决有关0的问题。另外,请您知道具体尺寸有多大?@maxywb。刚刚在我的机器上测试过。具体尺寸为512。但是根据下面的答案,这个数字应该在不同的机器上有所不同。发布的代码可能会出现内核启动失败,导致arraySize在513及以上或1025及以上没有修改的输出,具体取决于传递的特定GPU和编译命令。我想你的内核调用会出错,因为根据计算能力的不同,每个块最多只能启动1024个线程。当你进行usw错误检查时,你会看到这一点。没错,事实上,我只能用我认为你的内核调用来启动它,因为根据计算能力,每个块最多只能启动1024个线程。当你检查usw错误时,你会看到。没错,事实上我只能用