4

前の質問のフォローアップとして、クラスatomic<T>memory_orderパラメーターを使用してほとんどの操作を指定します。フェンスとは対照的に、このメモリ順序は、それが動作するアトミックにのみ影響します。おそらく、そのようないくつかのアトミックを使用することで、他のメモリの順序が重要でない並行アルゴリズムを構築できます。

だから私は2つの質問があります:

  1. 誰かが私に、個々のアトミック変数の順序付けから利益を得て、フェンスを必要としないアルゴリズム/状況の例を指摘できますか?
  2. このタイプの動作をサポートする最新のプロセッサはどれですか?つまり、コンパイラが特定の順序を通常のフェンスに変換するだけではありません。
4

1 に答える 1

4

std::atomic<T>変数に対する操作のメモリ順序付けパラメーターは、その操作自体の順序付けには影響しません。操作が他の操作と作成する順序付けの関係に影響します。

たとえばa.store(std::memory_order_release)、それ自体では、操作が他のものに関してどのように順序付けられているかについては何もわかりませんが、別のスレッドからaの呼び出しとペアになっている場合、これは他の操作を順序付けます ---他の変数(非アトミック変数を含む) へのすべての書き込みが完了しますそのロードが格納された値を読み取る場合、ストアを実行したスレッドによって、ロードを実行したスレッドに表示されます。a.load(std::memory_order_acquire)a

最新のプロセッサでは、操作の一部のメモリ順序付けは no-ops です。たとえば、x86 では、memory_order_acquirememory_order_consumeおよびmemory_order_releaseはロードおよびストア命令で暗黙的に指定され、個別のフェンスを必要としません。これらの場合、順序付けは、コンパイラが実行できる命令の並べ替えに影響を与えるだけです。

明確化: 命令内の暗黙的なフェンスは、すべてのメモリ順序制約がアトミック変数の個々の操作に関連付けられている場合、コンパイラが明示的なフェンス命令を発行する必要がないことを意味します。すべてに使用memory_order_relaxedし、明示的なフェンスを追加する場合、コンパイラはそれらのフェンスを命令として明示的に発行する必要があります。

たとえば、x86 では、XCHG命令は暗黙のmemory_order_seq_cstフェンスを伴います。したがって、x86 では、以下の 2 つの交換操作に対して生成されたコードに違いはありません。どちらも単一のXCHG命令にマップされます。

std::atomic<int> ai;
ai.exchange(3,std::memory_order_relaxed);
ai.exchange(3,std::memory_order_seq_cst);

ただし、次のコードで明示的なフェンス命令を取り除くコンパイラはまだ知りません。

std::atomic_thread_fence(std::memory_order_seq_cst);
ai.exchange(3,std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_seq_cst);

最終的にはコンパイラがその最適化を処理することを期待していますが、暗黙のフェンスがより良い最適化を可能にする同様のケースが他にもあります。

また、変数の直接操作にのみstd::memory_order_consume適用できます。

于 2011-04-06T07:32:32.333 に答える