我有一个节点树,我正在尝试将其复制到GPU内存。 Node看起来像这样:
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, 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;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
这是什么原因?
感谢。
答案 0 :(得分:4)
node_d->Children
是一个驻留在设备代码中的变量。您不能像主机代码那样直接使用它,就像使用第二个cudaMalloc
一样。 Morover,将主机指针复制到设备没有多大意义,因为您无法在设备代码中取消引用它们。
更好,更快的方法是:
memAlloc
可能效率低下(特别是在Windows系统中,当监视器连接到该GPU时)。此外,由于memAlloc
返回的地址始终与512字节对齐,因此实际上无法分配较小的内存块。因此,根据您当前的代码,即使内部只有2个子节点,每个子数组也将消耗至少512个字节。答案 1 :(得分:2)
看起来node_d本身就在gpu上。您无法使用 - &gt;访问gpu上的结构要么 。 您需要将node_d复制回主机,分配必要的数据并将其复制回来。