c 11 CAS で ABA カウンタを実装するにはどうすればよいですか?
2 つの値を同時にアトミックに更新するには、アトミックな隣接する構造体を作成します。 std::atomic
注特に x86 CPU の場合、アトミック オブジェクトはロックフリーである必要があります。 gcc7 以降のようなコンパイラは、インライン ロック cmpxchg16b を使用する代わりに libatomic を呼び出す場合があります。このようなシナリオでは、次の点を考慮してください:
これらの特性を示す C 11 コードの例を次に示します。
#include <atomic> #include <stdint.h> using namespace std; struct node { struct alignas(2*sizeof(node*)) counted_ptr { node * ptr; uintptr_t count; // use pointer-sized integers to avoid padding }; // hack to allow reading just the pointer without lock-cmpxchg16b, // but still without any C++ data race struct counted_ptr_separate { atomic<node *> ptr; atomic<uintptr_t> count_separate; // var name emphasizes that accessing this way isn't atomic with ptr }; static_assert(sizeof(atomic<counted_ptr>) == sizeof(counted_ptr_separate), "atomic<counted_ptr> isn't the same size as the separate version; union type-punning will be bogus"); // TODO: write member functions to read next.ptr or read/write next_and_count union { // anonymous union: the members are directly part of struct node alignas(2*sizeof(node*)) atomic<counted_ptr> next_and_count; counted_ptr_separate next; }; };
要約すると、2 つの値を同時にアトミックに変更するには、慎重な設計、コンパイラの考慮事項、およびアライメントの最適化が必要です。 。これらのガイドラインに従うことで、効率的で正しいコードを使用して C 11 にロックフリーの ABA カウンターを実装できます。
以上がCAS を使用して C 11 にロックフリーの ABA カウンターを実装し、パフォーマンスのオーバーヘッドを最小限に抑えるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。