フローグラフのエッジは、利用するライブラリーの依存関係を明確にします。同様に、function_node および multifunction_node オブジェクトの同時実行数の制限は、ランタイム・ライブラリーが許可する同時起動の最大数を制限します。これらの制限はライブラリーによる制限です。ライブラリーは自動的にデータ競合を防止しません。これらのメカニズムを利用して明示的にデータ競合を防ぐ必要があります。
例えば、次のコードにはノード f で参照されるグローバル・カウント・オブジェクトの同時アクセスを防ぐものが何もないため、データ競合が発生します。
graph g;
int src_count = 1;
int global_sum = 0;
int limit = 100000;
source_node< int > src( g, [&]( int &i ) -> bool {
if ( src_count <= limit ) {
i = src_count++;
return true;
} else {
return false;
}
} );
function_node< int, int > f( g, unlimited, [&]( int i ) -> int {
global_sum += i; // global_sum のデータ競合
return i;
} );
make_edge( src, f );
g.wait_for_all();
cout << "global sum = " << global_sum
<< " and closed form = " << limit*(limit+1)/2 << "\n";
上記の例を実行すると、データ競合により、予想よりも少ないグローバル合計が計算されるでしょう。f で許可される並列性を unlimited から 1 に変更することで、この例のデータ競合が回避され、各値が f で順番に処理されるようになります。例では、source_node がグローバルな値である src_count を更新しています。しかし、source_node は常にシリアルに実行されるため、データ競合は発生しません。