CUDA:从节点构建图形

CUDA:从节点构建图形,cuda,parallel-processing,gpgpu,Cuda,Parallel Processing,Gpgpu,我正在使用CUDA从节点列表构建一个无向图。每个节点都有一个三维坐标,如果节点之间的距离小于某个截止距离d,我的程序将在两个节点之间创建一条边 现在我以邻接列表的形式存储边。问题是,我有1024个线程异步计算成对距离。一旦节点A和B之间的边被“发现”,我需要增加节点A的边数,并将节点B放置在邻接列表中的“下一个可用”位置 这里,库达让我做噩梦。我希望邻接列表更新过程至关重要,但CUDA似乎没有提供atomicAdd()以外的任何东西。因此,每次运行代码时,我都会得到不可预测的行为和不同的邻接列表

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

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

这里,库达让我做噩梦。我希望邻接列表更新过程至关重要,但CUDA似乎没有提供atomicAdd()以外的任何东西。因此,每次运行代码时,我都会得到不可预测的行为和不同的邻接列表


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

您可以用a替换atomicAdd(),以产生可重复的结果。或者,您可以在单独的步骤中对结果进行排序。

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

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];
    }
for(int i=0;i
如果节点数量不够大(我想使用CUDA),可以将一个节点和所有其他节点之间的计算除以一个块的线程,每个线程计算相等部分的距离。使用
\uu syncthreads()
可确保
决定论。

谢谢。我已经试过了。它可以工作,但我发现大多数线程都处于空闲状态,这让我很恼火。我还使用了区域分解来限制每个节点的距离计算数量,每个块产生大约100个节点。我想我会接受异步写入的问题,并对每个块的节点进行修补,以便获得每个线程的最大占用率。顺便说一句,我有介于1E6和1E9之间的节点,所以这个策略并没有那么糟糕。事实上,如果大多数线程处于空闲状态,这是没有问题的。在这种情况下,重要的是每秒计算距离的数量,这取决于GPU流式多处理器(SM)的占用率和算法的效率。若正在运行的线程块完全占用了GPU,而其余线程块正在等待SMs的释放,那个么您将获得最大吞吐量。