次のループは、グラフのすべてのエッジを反復処理し、エンドノードが同じグループに属しているかどうかを判断してから、そのグループの合計エッジウェイトにエッジウェイトを追加します。
// 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
残念ながら、アトミック性の設定は、インクリメント、デクリメント、XORなど、通常は単一のプロセッサオペコードにコンパイルできる単純な式にのみ指定できます。たとえば、関数呼び出し、配列のインデックス付け、オーバーロードされた演算子、非PODタイプ、または複数のステートメントを含めることはできません。
このループを正しく並列化するには、何を使用する必要がありますか?