42

私が理解していないのか、ドキュメントが明確に定式化されていないのかはわかりません。

次の抜粋は、最新のドラフト (N3126、セクション 29.6) からの抜粋です。

bool atomic_compare_exchange_weak(volatile A* object, C * expected, C desired);
bool atomic_compare_exchange_weak(A* object, C * expected, C desired);
bool atomic_compare_exchange_strong(volatile A* object, C * expected, C desired);
bool atomic_compare_exchange_strong(A* object, C * expected, C desired);
bool atomic_compare_exchange_weak_explicit(volatile A* object, C * expected, C desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_weak_explicit(A* object, C * expected, C desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_strong_explicit(volatile A* object, C * expected, C desired, memory_order success, memory_order failure);
bool atomic_compare_exchange_strong_explicit(A* object, C * expected, C desired, memory_order success, memory_order failure);
bool A::compare_exchange_weak(C & expected, C desired, memory_order success, memory_order failure) volatile;
bool A::compare_exchange_weak(C & expected, C desired, memory_order success, memory_order failure);
bool A::compare_exchange_strong(C & expected, C desired, memory_order success, memory_order failure) volatile;
bool A::compare_exchange_strong(C & expected, C desired, memory_order success, memory_order failure);
bool A::compare_exchange_weak(C & expected, C desired, memory_order order = memory_order_seq_cst) volatile;
bool A::compare_exchange_weak(C & expected, C desired, memory_order order = memory_order_seq_cst);
bool A::compare_exchange_strong(C & expected, C desired, memory_order order = memory_order_seq_cst) volatile;
bool A::compare_exchange_strong(C & expected, C desired, memory_order order = memory_order_seq_cst);

注意: 弱い比較交換操作は誤って失敗する可能性があります。つまり、操作がオブジェクトの内容と同じであり、操作後の期待値と同じである前に、expected が指すメモリの内容を残したまま、false を返す場合があります。操作。[ 注: この誤った失敗により、より広いクラスのマシン (ロードロックされたストア条件付きマシンなど) での比較交換の実装が可能になります。偽の失敗の結果として、弱い比較交換のほぼすべての使用がループ状態になります。

それで、これはどういう意味ですか?

まず、誤って失敗する可能性がありますか?! なぜ失敗するのでしょうか?そして、彼らは「かもしれない」をどのように定義しますか?

第二に、「_strong」サフィックスと「_weak」サフィックスを持つ関数の違いは何なのか、まだわかりません。誰かが違いを説明できますか?

編集: それは私が libstdc++ 実装 (atomic_0.h) で見つけたものです:

bool compare_exchange_weak(
    __integral_type& __i1,
    __integral_type __i2,
    memory_order __m1,
    memory_order __m2
)
{
    __glibcxx_assert(__m2 != memory_order_release);
    __glibcxx_assert(__m2 != memory_order_acq_rel);
    __glibcxx_assert(__m2 <= __m1);
    return _ATOMIC_CMPEXCHNG_(this, &__i1, __i2, __m1);
}

bool compare_exchange_strong(
    __integral_type& __i1,
    __integral_type __i2,
    memory_order __m1,
    memory_order __m2
)
{
    __glibcxx_assert(__m2 != memory_order_release);
    __glibcxx_assert(__m2 != memory_order_acq_rel);
    __glibcxx_assert(__m2 <= __m1);
    return _ATOMIC_CMPEXCHNG_(this, &__i1, __i2, __m1);
}
4

2 に答える 2

45

メモは、 LL/SCアーキテクチャを参照して、手がかりを与えます。ウィキペディアの記事から:

更新が発生した場合、load-link によって読み取られた値がその後復元されたとしても、store-conditional は失敗することが保証されます。そのため、LL/SC ペアは、古い値が復元された場合に更新を検出しない比較交換 (CAS) が続く読み取りよりも強力です (ABA 問題を参照)。

問題のメモリ位置への同時更新がない場合、LL/SC の実際の実装は常に成功するとは限りません。コンテキスト スイッチ、別のロード リンク、または (多くのプラットフォームで) 別のロードまたはストア操作など、2 つの操作の間に例外的なイベントが発生すると、ストア条件が誤って失敗します。

LL/SC チップではcompare_exchange、LL/SC に関して実装されますが、誤って失敗する可能性があるためcompare_exchange_strong、失敗した場合に再試行するために追加のオーバーヘッドが必要になります。と の両方compare_exchange_strongを提供compare_exchange_weakすることで、プログラマーは、ライブラリで誤ったエラーを処理するか (この場合は を使用するcompare_exchange_strong)、または独自のコードで処理するか (この場合は を使用するcompare_exchange_weak)を決定できます。

于 2013-03-12T16:19:34.863 に答える
13

これは、ハードウェアが実装する共有メモリの一貫性モデルに関係しています。ある種の緩和された一貫性モデル (リリース セマンティクスなど) を実装するハードウェア アーキテクチャの場合、上記で言及した強力な操作はオーバーヘッドが高くなる可能性があるため、専門家はより弱い形式を使用して、緩和された一貫性でも適切に機能するアルゴリズムを実装できます。アーキテクチャ。

詳細については、例を参照してください。

http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf

http://kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.htmlの第 12 章および付録 C

于 2011-02-09T13:48:12.527 に答える