4

uint64_tTWO を同時にアトミックに更新できるようにする必要があるという問題があります。それらのそれぞれをアトミックに記述するのは簡単ですが (たとえば 2 つstd::atomic<uint64_t>)、それでも一方が更新されても他方が更新されないという状況が発生します。ロックとミューテックスを使用することも簡単に可能です。

uint64_tしかし、読み取り時にロックされないように、タイプのメンバー変数を引き続き使用できるように、ロックを一切使用せずに両方をアトミックに書き込みたいと考えています。これは、私のユースケースでは、何度も何度もそれらを読み取る必要があるためです。出来ますか?もしそうなら、どのように?

4

2 に答える 2

4

標準についてstd::atomicは、(強調鉱山)

プライマリstd::atomicテンプレートは、任意のTriviallyCopyable型 Tでインスタンス化できます。

struct Counters { int a; int b; }; // user-defined trivially-copyable type
std::atomic<Counters> cnt;         // specialization for the user-defined type

uint64_tしたがって、このような2 の構造体を作成できます

struct atomic128 {
    uint64_t a1, a2;
};

これは自明にコピー可能で ( で簡単に確認できますstd::is_trivially_copyable)、次に を使用しますstd::atomic<atomic128>自明にコピーできない場合、エラーが発生しますstd::atomic<type>

そうすれば、コンパイラーはロックフリーの更新メカニズムが利用可能であれば自動的に使用します。特別なことをする必要はありません。必要に応じて以下のいずれかで確認してください。

std::atomic_flag を除くすべてのアトミック型は、ロックフリーのアトミック CPU 命令を使用するのではなく、ミューテックスまたはその他のロック操作を使用して実装できます。アトミック型は時々ロックフリーになることも許されます: たとえば、特定の型 (x86-64 の CMPXCHG16B 命令など) に対してロックフリーのアトミック アクセスをサポートするサブアーキテクチャのみがサポートされている場合、アトミック型がロックフリーであるかどうかは不明な場合があります。実行時まで認識されます。

std::atomic_is_lock_freestd::atomic::is_lock_free

Compiler Explorerのデモを次に示します。ご覧のとおり、alock cmpxchg16bが発行されますが、GCC 7 以降では、使用可能な場合は内部的に使用__atomic_store_16するだけを呼び出します。cmpxchg16b

一部のプラットフォームlong doubleでは 128 ビット タイプまたは 128 ビットにパディングされているため、std::atomic<long double>別の解決策になる可能性がありますが、もちろんサイズとロックフリーかどうかを最初に確認する必要があります。

別の代替手段はBoost.Atomicです。マクロもあり、BOOST_ATOMIC_INT128_LOCK_FREEチェックBOOST_ATOMIC_LONG_DOUBLE_LOCK_FREEする

一部の CPU では、128 ビット SSE 操作もアトミックです。残念ながら、それを使用できるかどうかを確認する方法はありません。

以下も参照してください。

于 2013-10-16T06:58:38.450 に答える
2

直接行うことはできないと思いますが、ソフトウェアのトランザクショナル メモリ技術を使用してそれを偽造することはできます。特に、uint64_t-pairs のロックフリー リング バッファーを使用できます。この構成では、リング バッファの非アクティブな要素への書き込みは非アトミックに安全に実行できます。これは、"current-value-index" がアトミックに更新されるまで、誰もリング バッファのその要素から読み取らないためです。書き込みの終わり (インデックスが int32_t になる可能性があるため可能です)。

警告: このトリックは、短期間に値への書き込みが多すぎないことを保証できる場合にのみ機能します (「多すぎる」とは、「リング バッファーのスロット数よりも多い」ことを意味します)。また、ロックフリー プログラミングを 100% 正しく行うことは難しいことで知られているため、自分で作成するのではなく、これを実装する STM ライブラリを見つけることをお勧めします。

于 2013-10-16T06:57:56.633 に答える