最简单的(可能也是最好)的方法是改变你的结构使用节点指标,而不是指针。指针的问题在于设备具有不同的指针,即使您单独复制所有节点,它仍然无法工作,因为指针也需要更新为设备指针。不幸的是,OpenCL 1.2甚至不保证器件指针的有效期比单个内核调用更长。出于这个原因,你必须至少在设备上使用索引而不是指针。
修改您的结构是这样的:
typedef struct treeNode {
int key;
int left;
int right;
} treeNode_t;
之前建立的树你分配树节点的一个大阵,大到足以容纳所有节点。
treeNode_t nodes[MAX_NODES]; // or dynamic allocation
int first_free_node=0;
每次你通常会分配一个新的节点,您现在使用节点[first_free_node]来存储数据并增加first_free_node计数器。当您完成构建树时,您可以使用一个clEnqueueCopyBuffer调用将所有节点复制到设备。您只需将first_free_node * sizeof(treeNode_t)个字节从节点阵列的起始位置复制到设备。如果您无法更改主机树构建代码,则可以使用树的简单递归深度第一次传输来计算节点数并将节点从基于指针的格式转换为基于索引的格式。
在某些设备上,如果您转换您的树的结构,从结构的阵列排列的结构,你可能会得到更高的性能。将结构填充到每个节点16个字节也可以提供帮助。
如果你的树节点正好是20个字节,可以填充它,直到它变成32首或64个字节,然后重新计算,使得它们成为在地址空间连续的所有地址,使最小地址零,并从其他减去其价值和保存在其他一些字段中的旧地址(例如填充字段)然后在设备中计算,同时保持主机地址和设备地址的相对地址不变。 –
你打算在OpenCL中用这棵树做什么? – dtech