私は新しいC++ 11メモリモデルについて読んでいて、std::kill_dependency
関数に出くわしました(§29.3/14-15)。なぜそれを使いたいのか理解に苦しむ。
N2664 提案で例を見つけましたが、あまり役に立ちませんでした。
なしでコードを表示することから始めますstd::kill_dependency
。ここで、最初の行は依存関係を 2 番目の行に運び、依存関係をインデックス付け操作に運び、次に依存関係をdo_something_with
関数に運びます。
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[r2]);
std::kill_dependency
2行目と索引付けの間の依存関係を壊すために使用する別の例があります。
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(a[std::kill_dependency(r2)]);
私が知る限り、これは、インデックス作成と への呼び出しdo_something_with
が、2 行目の前に順序付けられた依存関係ではないことを意味します。N2664によると:
これにより、コンパイラは
do_something_with
、たとえば、 の値を予測する投機的最適化を実行することにより、への呼び出しを並べ替えることができますa[r2]
。
値を呼び出すにdo_something_with
は、値a[r2]
が必要です。仮に、配列がゼロで埋められていることをコンパイラが「知っている」場合、その呼び出しを最適化do_something_with(0);
し、他の 2 つの命令に対してこの呼び出しを必要に応じて並べ替えることができます。次のいずれかを生成できます。
// 1
r1 = x.load(memory_order_consume);
r2 = r1->index;
do_something_with(0);
// 2
r1 = x.load(memory_order_consume);
do_something_with(0);
r2 = r1->index;
// 3
do_something_with(0);
r1 = x.load(memory_order_consume);
r2 = r1->index;
私の理解は正しいですか?
他の方法で別のスレッドと同期する場合、呼び出しとこの別のスレッドdo_something_with
の順序に関して、これはどういう意味ですか?x.load
私の理解が正しいと仮定すると、私を悩ませることがまだ 1 つあります。コードを書いているとき、どのような理由で依存関係を破棄することを選択するのでしょうか?