顺序循环、临界区、原子更新。
我有一个由顶点和边组成的二维图。
对于每个顶点,我想计算自由度 (dof) 的数量。 顶点 dof = 连接到该顶点的边数。
我所做的是:
std::vector<size_t> dofs(graph.getNumVertices(), 0);
#pragma omp parallel for
for (int edgeInd = 0; edgeInd < graph.getNumEdges(); ++edgeInd)
{
#pragma omp atomic
++dofs[graph.getEdge(edgeInd).v1.index];
#pragma omp atomic
++dofs[graph.getEdge(edgeInd).v2.index];
}
效果符合预期。
我的问题:
所有边都分布在不同的线程中。假设只有两个线程:1 和 2。
边缘可以有:
问题1:原子更新是否仅在需要时“自行激活”?关键部分(如果应用的话)是否始终处于活动状态?
意思是,下表正确吗(?):
一条边可以有:ATOMIC CRITICAL
问题2:
理论上,我期望:
正确吗?
正如 @PierU 的评论所观察到的,你的原子指令使代码正确,但可能有效地串行。您需要不同的方法。
请参阅我之前对非常类似问题的回答:
https://stackoverflow.com/a/77273690/2044454
https://stackoverflow.com/a/76854330/2044454
用 C++ 编写代码要容易得多,但您可以用 C 来模拟它。