さまざまなロックフリー アルゴリズムには、高速パスでのロードまたはストアの順序付け要件がありません。たとえば、この仕事を盗むhttp://www.cs.rice.edu/~vs3/PDF/ppopp.09/p45-michael.pdfでは、盗む操作にはアトミックな比較と交換が必要ですが、頻繁な操作は(put and take) は特に、順序の制約がまったく必要ないように設計されています。私は他の多くのケースでこの種のパターンに出くわしました。
では、メモリの制約を強制せずに std アトミック変数にアクセスする方法がないのはなぜでしょうか? x-86(-64) では、memory_order_relaxed は CPU バリア命令を挿入しませんが、(少なくとも Visual C++ 2012 の実装で確認できることから) コンパイラの並べ替えを防ぎますが、それでも確実にパフォーマンスが低下します。実際、メモリの順序は実行時のパラメーターであるため、分岐が発生するというペナルティもあります。組み合わせて、それは事態をさらに悪化させます。次の Visual C++ 2012 実装のコードは、switch ステートメントが memory_order_relaxed であると判断した後に、uint32_t 値を atomic_uint32_t に格納します (xatomic.h を参照)。
_Compiler_barrier();
__asm
{
mov eax, _Value;
mov edx, _Tgt;
mov [edx], eax;
}
_Compiler_barrier();
そこからの memory_order_relaxed を使用したロードは、最終的に実行されます
_Value = _InterlockedOr((volatile long *)_Tgt, 0);
_InterlockedOr 組み込みが完全な CPU バリア (xatomic.h) であるため、これはさらに悪いことです。
したがって、1) 非メモリ順序付けアクセスが std API の一部ではない理由、および 2) 独自のアトミック API をローリングする以外の回避策は何か、アトミック クラスの醜い reinterpret_cast を非アトミック型に変更し、 sizeof と offsetof のコンパイル時のチェックを行っていますか?
(私がターゲットとするアーキテクチャー上で通常のロードとストアがすでにアトミックである整数型に関心があるため、アトミック アクセスと非アトミック アクセスを混在させることについて話しているわけではないことに注意してください。)