8

重複の可能性:
同時実行: C++11 メモリ モデルのアトミックおよび揮発性

C++11<atomic>仕様では、鮮度の保証はありますか? さまざまなメモリ順序の説明は、並べ替えのみを扱っています (私が見た限り)。

具体的には、この状況では:

#include <atomic>

std::atomic<int> cancel_work(0);

// Thread 1 is executing this function
void thread1_func() {

    ...

    while (cancel_work.load(<some memory order>) == 0) {
        ...do work...
    }
}


// Thread 2 executes this function
void thread2_func() {

    ...

    cancel_work.store(1, <some memory order>);

    ...

}

スレッド 1 とスレッド 2 が 以外のデータを共有しない場合、順序の保証は必要なく、ストアとロードの両方で十分であるcancel_workように思えます。しかし、これは、スレッド 1 がローカル キャッシュ ラインをメイン メモリから更新せずに繰り返し読み取るのではなくstd::memory_order_relax、更新を確認することを保証するものでしょうか? cancel_workそうでない場合、その保証を行うために最低限必要なものは何ですか?

4

3 に答える 3

6

それを保証するものは何もありません。すべては注文に関するものです。memory_order_seq_cst物事が単一の完全な順序で起こることを保証するだけでも. 理論的には、コンパイラ/ライブラリ/CPUcancel_storeは、プログラムの最後からすべてのロードをスケジュールできます。

29.3p13 には一般的な声明があります。

実装では、妥当な時間内にアトミック ストアをアトミック ロードから見えるようにする必要があります。

しかし、「合理的な時間」を構成するものについての仕様はありません。

したがってmemory_order_relaxed、問題ないはずですがmemory_order_seq_cst、キャッシュラインがより早くリロードされる可能性があるため、一部のプラットフォームではよりうまく機能する可能性があります。

于 2013-02-04T13:31:18.810 に答える
3

この答えは私の質問にも答えているようです。うまくいけば、私の質問がグーグル社員がそれをよりよく見つけるのに役立つことを願っています.

スレッド 1cancel_workは「合理的な時間」内に更新を「すべき」ですが、正確に何が合理的かは (明らかに) 指定されていません。

于 2013-02-04T13:27:44.247 に答える
2

[コンパイラによってインライン化されていない] 関数を呼び出すと、すぐにローカルではない変数を保持するレジスタが自動的に再ロードされます。そのため、thread1_func() を実行しているプロセッサが に基づいてキャッシュ コンテンツをフラッシュまたは更新している限り、動作しstoreます。

memory_order_relaxデータが(将来のある時点で)他のプロセッサキャッシュからフラッシュされることを確認する必要があります[これはx86では自動ですが、すべてのタイプのプロセッサではありません。たとえば、特定のARMプロセッサでは「コード駆動のフラッシュ」が必要です]。 [通常の変数またはアトミック変数への] 他の書き込みの前に発生することは保証されていません。

また、メモリの順序は現在のスレッド/プロセッサにのみ影響することに注意してください。ストアまたはロード中に別のスレッドまたはプロセッサが何をするかは、完全にそのスレッド/プロセッサ次第です。これが意味することはthread1_func()、あなたの場合、値が他のプロセッサ/スレッドによって書き込まれた0後、しばらくの間値を読み取ることができる可能性があるということです。1すべてのアトミック操作が保証するのは、いずれかが OLD 値または NEW 値を取得することですmemory_order_relax。ただし、使用しているメモリの順序に関係なく、アトミックは[正しい実装を前提として]値が最終的に更新されることを保証する必要があります。リラックスした場合に判断するのが難しいだけです。

于 2013-02-04T13:37:28.313 に答える