コンパイラのみのメモリバリア(std::atomic_signal_fenceなど)はいつ役立つのでしょうか?質問する

コンパイラのみのメモリバリア(std::atomic_signal_fenceなど)はいつ役立つのでしょうか?質問する

の概念コンパイラフェンスメモリモデル、バリア、順序、アトミックなどについて読んでいるときによく出てきますが、通常はまたペアになっているCPUフェンス予想通りです。

しかし、時々、フェンスの構造について読むことがあります。のみコンパイラーに適用します。この例としては、C++11のstd::atomic_signal_fence関数があります。翻訳元:

std::atomic_signal_fence は、メモリ順序付けのための CPU 命令が発行されないことを除いて、std::atomic_thread_fence と同等です。順序付け命令として、コンパイラによる命令の並べ替えのみが抑制されます。

このトピックに関連して 5 つの質問があります。

  1. 名前からもわかるようにstd::atomic_signal_fence非同期割り込み(スレッドがカーネルによってプリエンプトされてシグナルハンドラを実行するなど)のみケースコンパイラのみフェンスは役に立ちますか?

  2. その有用性は、以下を含むすべてのアーキテクチャに当てはまるか?強く秩序立ったのようなものx86

  3. できる特定のの有用性を示す例が提供されるコンパイラのみフェンス?

  4. を使用する場合、 を使用することと を順序付けるstd::atomic_signal_fenceことに違いはありますか? (違いはないと思います。)acq_relseq_cst

  5. この質問は最初の質問でカバーされているかもしれませんが、とにかく具体的に聞きたいほど興味があります。これまでアクセスにフェンスを使う必要があるのかthread_local​​?(もし必要になったとしても、コンパイラのみフェンスなどのatomic_signal_fenceツールを選択するようにしてください。

ありがとう。

ベストアンサー1

5つの質問すべてに答えるには:


1) コンパイラフェンス(CPUフェンスなしで単独で)は、状況:

  • 実施するためにメモリ順序制約 単一スレッドと非同期割り込みハンドラの間同じスレッド (シグナル ハンドラーなど) にバインドされます。

  • 実施するためにメモリ順序制約 すべてのスレッドが同じCPUコア上で実行されることが保証されている複数のスレッド間つまり、アプリケーションはシングルコアシステム、またはアプリケーションが特別な措置を講じる(プロセッサの親和性) により、データを共有するすべてのスレッドが同じコアにバインドされるようになります。


2) 基盤となるアーキテクチャのメモリ モデルは、それが強い順序付けであるか弱い順序付けであるかに関係なく、状況でコンパイラ フェンスが必要かどうかには影響しません。


3) ここは疑似コードこれは、コンパイラ フェンスを単独で使用して、スレッドと同じスレッドにバインドされた非同期シグナル ハンドラー間のメモリ アクセスを十分に同期する方法を示しています。

void async_signal_handler()
{
    if ( is_shared_data_initialized )
    {
        compiler_only_memory_barrier(memory_order::acquire);
        ... use shared_data ...
    }
}

void main()
{
// initialize shared_data ...
    shared_data->foo = ...
    shared_data->bar = ...
    shared_data->baz = ...
// shared_data is now fully initialized and ready to use
    compiler_only_memory_barrier(memory_order::release);
    is_shared_data_initialized = true;
}

重要な注意点:この例では、が初期化してフラグを設定するasync_signal_handler同じスレッドにバインドされていると想定しています。つまり、アプリケーションはシングルスレッドであるか、それに応じてスレッドシグナルマスクを設定します。そうでない場合、コンパイラフェンスは不十分であり、shared_datais_initializedCPUフェンスも必要になるでしょう。


4)それらは同じであるはずです。 acq_relどちらもseq_cst完全な (双方向の) コンパイラ フェンスとなり、フェンス関連の CPU 命令は発行されません。「シーケンシャル コンシステンシ」の概念は、複数のコアとスレッドが関係する場合にのみ適用され、atomic_signal_fence実行の 1 つのスレッドにのみ適用されます。


5)いいえ。(もちろん、スレッドローカルデータが非同期シグナルハンドラからアクセスされる場合は、コンパイラフェンスが必要になるかもしれません。)それ以外の場合、コンパイラ(およびCPU)は、そのスレッドローカルデータに関してプログラムの観察可能な動作を変更しない方法でのみメモリアクセスを並べ替えることができるため、フェンスはスレッドローカルデータでは必要ありません。シーケンスポイントシングルスレッドの観点からは、マルチスレッド プログラムのスレッドローカル スタティックは、シングルスレッド プログラムのグローバル スタティックと同じであると論理的に考えることができます。どちらの場合も、データは単一のスレッドからのみアクセス可能であり、データ競合の発生を防ぎます。

おすすめ記事