標準について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_free
とstd::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 操作もアトミックです。残念ながら、それを使用できるかどうかを確認する方法はありません。
以下も参照してください。