将多分支树复制到GPU内存

我有一个节点树,我试图将其复制到GPU内存。 Node看起来像这样:

struct Node { char *Key; int ChildCount; Node *Children; } 

我的复制function如下所示:

 void CopyTreeToDevice(Node* node_s, Node* node_d) { //allocate node on device and copy host node cudaMalloc( (void**)&node_d, sizeof(Node)); cudaMemcpy(node_d, node_s, sizeof(Node), cudaMemcpyHostToDevice); //test printf("ChildCount of node_s looks to be : %d\n", node_s->ChildCount); printf("Key of node_s looks to be : %s\n", node_s->Key); Node *temp; temp =(Node *) malloc(sizeof(Node)); cudaMemcpy(temp, node_d, sizeof(Node), cudaMemcpyDeviceToHost); printf("ChildCount of node_d on device is actually : %d\n", temp->ChildCount); printf("Key of node_d on device is actually : %s\n", temp->Key); free(temp); // continue with child nodes if(node_s->ChildCount > 0) { //problem here cudaMalloc( (void**)&(node_d->Children), sizeof(Node)*(node_s->ChildCount)); cudaMemcpy(node_d->Children, node_s->Children, sizeof(Node)*node_s->ChildCount, cudaMemcpyHostToDevice); for(int i=0;iChildCount;i++) { CopyTreeToDevice(&(node_s->Children[i]), &(node_d->Children[i])); } } } 

但我有一个问题:

 cudaMalloc( (void**)&(node_d->Children), sizeof(Node)*(node_s->ChildCount)); 

给我访问冲突exception。测试部分工作顺利。初始化字段没有问题。

这是测试部分的输出:

 ChildCount of node_s looks to be : 35 Key of node_s looks to be : root ChildCount of node_d on device is actually : 35 Key of node_d on device is actually : root 

这是什么原因?

谢谢。

node_d->Children是驻留在设备代码中的变量。 您不能像主机代码那样直接使用它,就像使用第二个cudaMalloc 。 Morover,将主机指针复制到设备没有太大意义,因为您无法在设备代码中取消引用它们。

一种更好,更快捷的方法是:

  • 为整棵树预分配一个大arrays。
  • 使用数组索引而不是指针。 索引的有效性将在转移到设备和从设备转移时保留。
  • 在设备上分配整个arrays一次。 拥有多个memAlloc可能效率低下(特别是在Windows系统中,当监视器连接到该GPU时)。 此外,由于memAlloc返回的地址始终与512字节对齐,因此实际上无法分配较小的内存块。 因此,根据您当前的代码,即使内部只有2个子节点,每个子数组也将消耗至少512个字节。
  • 将整个arrays从主机复制到设备。 这比拥有多个memCopy指令快得多,即使您实际复制了一些未使用的额外内存区域。

看起来node_d本身就在gpu上。 您无法使用 – >或访问gpu上的结构。 您需要将node_d复制回主机,分配必要的数据并将其复制回来。