问题描述
|
我有一棵节点树,我正在尝试将其复制到GPU内存。节点看起来像这样:
struct Node
{
char *Key;
int ChildCount;
Node *Children;
}
我的复制函数如下所示:
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,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;i<node_s->ChildCount;i++)
{
copyTreetoDevice(&(node_s->Children[i]),&(node_d->Children[i]));
}
}
}
但我有一条线的问题:
cudamalloc( (void**)&(node_d->Children),sizeof(Node)*(node_s->ChildCount));
给我访问冲突异常。测试部分工作顺利。初始化字段没有问题。
这是测试部分的输出:
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
是驻留在设备代码中的变量。您不能像第二个ѭ5那样直接通过主机代码使用它。 Morover,将主机指针复制到设备没有太大意义,因为您无法在设备代码中取消引用它们。
更好,更快的方法是:
为整个树预分配一个大数组。
使用数组索引而不是指针。在与设备之间进行传输时,索引的有效性将得以保留。
在设备上一次分配整个阵列。具有多个ѭ6可能效率不高(尤其是在Windows系统中,当监视器连接到该GPU时)。另外,由于“ 6”返回的地址始终与512个字节对齐,因此实际上您无法分配较小的内存块。因此,根据您当前的代码,即使其中只有2个子代,每个子代数组也会占用至少512个字节。
将整个阵列一次从主机复制到设备。这比拥有多个memCopy指令要快得多,即使您实际上复制了一些未使用的额外内存区域也是如此。
, 看起来node_d本身在gpu上。您无法使用->或访问gpu上的结构。
您需要将node_d复制回主机,分配必要的数据并将其复制回。