CUDA的内存复制:关于GPU的数据复制问题

最近在使用cuda平台进行一些多线程的编程,其中涉及到把数据从内存复制到显存,然后从显存复制到内存的操作。其中复制操作有很重要的一点是,假如是复制数组,内存空间必须是连续的。其中一维数组本身是连续的,所以没有问题。但是对于二维数组和三维数组等等,需要一开始就要分配好空间不能使用new或者malloc来动态分配,否则会出现复制后没有效果,或者其他意想不到的后果。

我刚开始是用动态创建数组的,即new,结果运行程序后,发现cpu_graph没有改变,后来把定义改为确定大小的数组后,才能复制成功。

整个工作流程大概是:

[c language=”++”]
GraphAll *gpu_graph;
//在gpu上分配内存
cudaMalloc((void **)&gpu_graph, sizeof(cpu_graph));
//把数据从内存复制到显存
cudaMemcpy(gpu_graph, &cpu_graph, sizeof(cpu_graph), cudaMemcpyHostToDevice);
//进行数据处理
SiukwanTest(gpu_graph);
//把在gpu中处理完毕的数据从显存复制到内存
cudaMemcpy(&cpu_graph, gpu_graph, sizeof(cpu_graph), cudaMemcpyDeviceToHost);
//释放显存
cudaFree(gpu_graph);
[/c]

刚开始的GraphAll变量定义如下,基本采用了指针,进行动态分配:

[c language=”++”]
struct GraphNode
{
char **shape;
int x ;
int y ;
};
//记录每种图形的变形,原始,旋转,翻转,不除去重复的,共有8种
struct GraphFormat
{
GraphNode *format;
int formatCount;
};
//存储所有图形
struct GraphAll
{
GraphFormat *graph;
int graphCount;
}cpu_graph;//cpu图形定义为全局变量
[/c]

由于进行动态分配,地址空间不连续,导致复制失败。后面我把变量改成确定大小的数组,如下,然后同样的程序,复制成功了:

[c language=”++”]
struct GraphNode
{
char shape[5][5];
int x ;
int y ;
};
//记录每种图形的变形,原始,旋转,翻转,不除去重复的,共有8种
struct GraphFormat
{
GraphNode format[8];
int formatCount;
};
//存储所有图形
struct GraphAll
{
GraphFormat graph[12];
int graphCount;
}cpu_graph;//cpu图形定义为全局变量
[/c]

Leave a Reply

Your email address will not be published. Required fields are marked *