14

特定の方法でメモリを解釈する複数のプロセス間で共有メモリがあります。元:

DataBlock {
int counter;
double value1;
double ...    }

私が望むのは、カウンターがアトミックに更新/インクリメントされることです。そして、そのアドレスでメモリ解放が行われるようにします。たとえば、共有メモリを使用していない場合は、次のようになります

std::atomic<int> counter;
atomic_store(counter, newvalue, std::memory_order_release); // perform release     operation on the affected memory location making the write visible to other threads

ランダムなメモリ位置でこれを達成するにはどうすればよいですか (上記の DataBlock カウンターであると解釈されます)。アーキテクチャ (x86 Linux) の要求に応じてアドレスが整列されていることを保証できます。

  1. 更新をアトミックにする - どうやって?(つまり、atomicupdate(addr, newvalue))
  2. マルチコアのメモリ同期 - (つまり、memorysync(addr)) - 私が見ることができる唯一の方法は、 std::atomic_thread_fence(std::memory_order_release) を使用することです - しかし、これは「すべてのアトミックストアとリラックスしたアトミックストアのメモリ同期順序を確立します」 - それは私にとってはやり過ぎです-カウンターの場所を同期させたいだけです。どんな考えでも感謝します。
4

3 に答える 3

14

ここで権限をもってお答えすることはできませんが、役立つかもしれない関連情報を提供できます。

  1. ミューテックスは、共有メモリ内に作成したり、クロスプロセス用に作成したりできます。Pthread には特別な作成フラグがあります。それが共有メモリを使用するのか、それともハンドルを共有するのか思い出せません。Linuxの「futex」は共有メモリを直接使用できます(ユーザーアドレスは異なる場合がありますが、基になる実際のアドレスは同じである必要があります)

  2. ハードウェア アトミックはメモリ上で動作し、プロセス変数では動作しません。つまり、チップは変数を変更しているプログラムを気にしません。したがって、最下位レベルのアトミックは当然クロスプロセスになります。同じことがフェンスにも当てはまります。

  3. C++11 はクロスプロセス アトミックの指定に失敗します。ただし、それらがロックフリーである場合 (フラグを確認してください)、クロスプロセスが機能しないようにコンパイラーがそれらを実装する方法を確認するのは困難です。しかし、ツール チェーンと最終的なプラットフォームに大きな信頼を置くことになります。

  4. CPU の依存関係の保証は実メモリ アドレスも追跡するため、プログラムがスレッド化された形式で正しい限り、マルチプロセス形式でも (可視性に関して) 正しいはずです。

  5. Kerrek は正しいです。抽象マシンは、実際には複数のプロセスについて言及していません。ただし、その同期の詳細は、マルチスレッドと同様にインタープロセスにも同様に適用されるように記述されています。これは#3に関連しています。コンパイラがこれを台無しにするのは難しいでしょう。

簡単に言えば、これを行うための標準に準拠した方法はありません。ただし、標準がマルチスレッドを定義する方法に依存すると、高品質のコンパイラに対して行うことができる多くの仮定があります。

最大の問題は、アトミックを単純に共有メモリに割り当て (新しい配置)、機能させることができるかどうかです。明らかに、これは真のハードウェア アトミックである場合にのみ機能します。ただし、高品質のコンパイラ/ライブラリを使用すると、C++ アトミックが共有メモリ内で機能するはずです。

動作確認をお楽しみください。:)

于 2012-01-06T17:30:22.157 に答える
6

Linux を使用しているため、gccatomic built-inのgcc ドキュメントによると、...__sync_fetch_and_add()のアドレスにatomic built-in を使用できます。これは、リリース操作ではなく、完全なメモリ フェンスも実装しますが、単純なロードではなく、読み取り-変更-書き込み操作が実際に必要な場合 (つまり、カウンターのインクリメントは単なるロードではなく、値を読み取り、変更し、最後に書き戻す必要があります)、フルメモリ フェンスこの操作に正しいメモリ順序を適用するには、より良い選択になるでしょう。counter

于 2012-01-06T19:01:59.017 に答える