以下循环遍历图的所有边缘,确定末端节点是否属于同一组,然后将边缘权重添加到该组的总边缘权重。

// TODO: parallel
FORALL_EDGES_BEGIN((*G)) {
    node u = EDGE_SOURCE;
    node v = EDGE_DEST;
    cluster c = zeta[u];
    cluster d = zeta[v];
    if (c == d) {
        // TODO: critical section
        intraEdgeWeight[c] += G->weight(u, v);
    } // else ignore edge
} FORALL_EDGES_END();

我想将它与 OpenMP 并行化。我认为if语句中的代码是关键部分,如果线程在中间中断,可能会导致争用条件和错误结果(对吗?)。

如果可以自动进行+=操作,那么我相信问题已解决(正确吗?)。但是,我在atomic指令looked up中声明:



我应该使用什么来正确并行化此循环?

最佳答案

实际上atomic update接受的语法是:

其中x是标量l值表达式,expr是任何表达式,包括函数调用,唯一的限制是它必须是标量类型。编译器会注意将中间结果存储在一个临时变量中。
有时候,最好引用标准文档,而不是阅读Internet上的教程。遵守OpenMP 3.1标准示例A.22.1c:

float work1(int i)
{
  return 1.0 * i;
}
...
#pragma omp atomic update
x[index[i]] += work1(i);

关于c++ - 如何使用OpenMP并行化更新总和,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13857316/

10-14 21:01