2

並列ループの前に がstd::vectorいっぱいstd::pair<Object, bool>です。ブール値はすべて に初期化されtrueます。ループはおおよそ次のようになります。

for (int x = 0; x < xMax; ++x) // can parallelising the loop in x cause a data race?
    for (int y = 0; y < yMax; ++y)
        for (auto& i : vector)
            if (i.first.ConstantFunctionDependingOnlyOnInput(x, y))
                i.second = false;

これまで boolfalseを この bool の結果に対して行われる操作は、その後単一のスレッドで行われます (bool == true標準アルゴリズムを使用してベクター内のすべての要素を消去します。

ここでアドバイスをいただければ幸いです。を使用するつもりでしstd::atomicsたが、もちろん、std::vectorコピー構築可能ではないため、 a では使用できません。

乾杯!

4

2 に答える 2

3

これが失敗する可能性のある例を次に示します。実際のコードはまさにこの方法で失敗しています。

    for (auto& i : vector)
        if (i.first.ConstantFunctionDependingOnlyOnInput(x, y))
            i.second = false;

コンパイラは、このコードを次のように最適化します。

for (auto& i : vector);
{
     bool j = i.second;
     bool k = i.first.Function(x, y);
     i.second = k ? false : j;
}

これにより、あるスレッドが別のスレッドの結果を上書きする可能性があります。無条件の書き込みは、予測を誤ることができないため、条件付きの書き込みよりも安価になる可能性があるため、これは正当な最適化になる可能性があります。

于 2015-08-25T20:07:00.363 に答える
-2

その通りです。これは、実際のシステムで期待どおりに動作します (データ競合はありません)。C++ 標準による公式には未定義の動作ですが、実際のシステムはそのようには機能しません。これは、これを含むより広範な質問に対する回答です

ただし、これは公式には未定義であるという標準のテキストは次のとおりです。

2 つの式の評価は、一方がメモリ ロケーション (1.7) を変更し、もう一方同じメモリ ロケーションにアクセスまたは変更する場合に競合します。

標準で保証された安全性が必要な場合は、アトミックメモリ アクセスを検討できます。

于 2015-08-25T20:06:27.597 に答える