最近在使用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]