CUDA:从节点构建图形

时间:2012-12-08 20:43:08

标签: cuda parallel-processing gpgpu

我正在使用CUDA从节点列表构建无向图。每个节点都有一个三维坐标,如果节点间隔小于一些截止距离d,我的程序会在两个节点之间创建一条边。

现在我以邻接列表的形式存储边缘。问题是,我有1024个线程异步计算成对距离。一旦在节点A和B之间“发现”边缘,我需要增加节点A的边数,并将节点B放在邻接列表中的“下一个可用”位置。

在这里,CUDA给了我噩梦。我希望adjacency-list-update过程至关重要,但CUDA似乎没有提供除atomicAdd()之外的任何东西。因此,每次运行代码时,我都会遇到不可预测的行为和不同的邻接列表。

有没有办法异步创建邻接列表?也许通过更聪明的数据结构?

2 个答案:

答案 0 :(得分:1)

您可以使用prefix scan替换atomicAdd()以获得可重现的结果。或者,您可以在单独的步骤中对结果进行排序。

答案 1 :(得分:1)

如果节点数足够大,我会将一个线程映射到一个节点,因此每个节点计算到所有其他节点的距离,并将它们存储到其私有邻接列表中。在这种情况下,如果定义了计算顺序(通过节点列表的排序来完成),则不会发生不确定性。一些代码:

for(int i = 0; i < listOfNodes.length(); i++)
    if(dist(listOfNodes[threadId], listOfNodes[i]) < cutoffDist) {
        int n = adjacencyLists_sizes[threadId]++;
        adjacencyLists[threadId][n-1] = listOfNodes[i];
    }

如果节点数量不够大(使用CUDA我认为是),您可以在一个节点和一个块的线程中的所有其他节点之间划分计算,每个线程计算相等的距离部分。使用__syncthreads()可确保 确定性。