23

プロセス間で共有メモリセグメントにアクセスしても、スレッド間でプロセスメモリにアクセスする場合に比べてパフォーマンスが低下しないとよく耳にします。つまり、マルチスレッドアプリケーションは、共有メモリを使用する一連のプロセスよりも高速ではありません(ロックやその他の同期の問題を除く)。

しかし、私には疑問があります。

1)shmat()は、ローカルプロセスの仮想メモリを共有セグメントにマップします。この変換は、共有メモリアドレスごとに実行する必要があり、かなりのコストがかかる可能性があります。マルチスレッドアプリケーションでは、追加の変換は必要ありません。共有メモリにアクセスしない通常のプロセスと同様に、すべてのVMアドレスが物理アドレスに変換されます。

2)共有メモリセグメントは、カーネルによって何らかの方法で維持される必要があります。たとえば、shmに接続されているすべてのプロセスが停止しても、shmセグメントはまだ稼働しており、最終的には新しく開始されたプロセスから再度アクセスできます。shmセグメントでのカーネル操作に関連するオーバーヘッドが発生する可能性があります。

マルチプロセス共有メモリシステムは、マルチスレッドアプリケーションと同じくらい高速ですか?

4

5 に答える 5

14

1)shmat()は、ローカルプロセスの仮想メモリを共有セグメントにマップします。この変換は、共有メモリアドレスごとに実行する必要があり、shmアクセスの数に比べてかなりのコストがかかる可能性があります。マルチスレッドアプリケーションでは、追加の変換は必要ありません。共有メモリにアクセスしない通常のプロセスと同様に、すべてのVMアドレスが物理アドレスに変換されます。

共有ページを設定するための初期コスト(呼び出すプロセスでページテーブルにデータを入力する)を除けば、通常のメモリアクセスと比較してオーバーヘッドはありませんshmat()。ほとんどの種類のLinuxでは、共有メモリ4KBあたり1ページ(4または8バイト)です。 。

ページが共有で割り当てられているか、同じプロセス内で割り当てられているかにかかわらず、(関連するすべての比較に対して)同じコストです。

2)共有メモリセグメントは、カーネルによって何らかの方法で維持される必要があります。パフォーマンスの観点から「どういうわけか」が何を意味するのかわかりませんが、たとえば、shmに接続されているすべてのプロセスが停止しても、shmセグメントはまだ稼働しており、最終的には新しく開始されたプロセスから再度アクセスできます。shmセグメントの存続期間中にカーネルがチェックする必要があるものに関連して、少なくともある程度のオーバーヘッドが必要です。

共有されているかどうかに関係なく、メモリの各ページには「構造体ページ」が添付されており、ページに関するデータが含まれています。項目の1つは参照カウントです。ページがプロセスに渡されると(「shmat」またはその他のメカニズムを介して)、参照カウントが増加します。何らかの方法で解放されると、参照カウントがデクリメントされます。デクリメントされたカウントがゼロの場合、ページは実際に解放されます。それ以外の場合、「それ以上何も起こりません」。

割り当てられた他のメモリと比較して、オーバーヘッドは基本的にゼロです。同じメカニズムがとにかくページの他の目的に使用されます-たとえば、カーネルによっても使用されているページがあり、プロセスが停止した場合、カーネルは、カーネルによってリリースされるまでそのページを解放しないことを知る必要があります。同様に、ユーザープロセス。

「フォーク」が作成されたときにも同じことが起こります。プロセスがフォークされると、親プロセスのページテーブル全体が基本的に子プロセスにコピーされ、すべてのページが読み取り専用になります。書き込みが発生するたびに、カーネルによって障害が発生し、そのページがコピーされます。そのため、そのページのコピーが2つあり、書き込みを行うプロセスは、他のプロセスに影響を与えることなく、そのページを変更できます。子(または親)プロセスが停止すると、もちろん、両方のプロセスがまだ所有しているすべてのページ[書き込まれることのないコードスペースや、おそらく触れられない共通データの束など]は明らかにできません。両方のプロセスが「デッド」になるまで解放されます。繰り返しになりますが、ここでは参照カウントページが役立ちます。これは、各ページの参照カウントのみをカウントダウンするためです。

共有ライブラリでもまったく同じことが起こります。1つのプロセスが共有ライブラリを使用している場合、そのプロセスが終了すると解放されます。ただし、2つ、3つ、または100のプロセスが同じ共有ライブラリを使用する場合、ページが不要になるまでコードをメモリに保持する必要があります。

したがって、基本的に、カーネル全体のすべてのページはすでに参照カウントされています。オーバーヘッドはほとんどありません。

于 2013-01-24T23:10:10.510 に答える
5

2つのスレッドまたはプロセスが同じメモリにアクセスしているときにマイクロエレクトロニクスレベルで何が起こっているかを考えると、いくつかの興味深い結果があります。

興味深いのは、CPUのアーキテクチャにより、複数のコア(つまりスレッドとプロセス)が同じメモリにアクセスできるようにする方法です。これは、L1キャッシュ、次にL2、L3、最後にDRAMを介して行われます。そのすべてのコントローラー間で非常に多くの調整を行う必要があります。

CPUが2つ以上あるマシンの場合、その調整はシリアルバスを介して行われます。2つのコアが同じメモリにアクセスしているときと、データが別のメモリにコピーされているときに発生するバストラフィックを比較すると、トラフィック量はほぼ同じです。

したがって、マシンのどこで2つのスレッドが実行されているかに応じて、データをコピーする場合と共有する場合の速度の低下はほとんどありません。

コピーは、1)memcpy、2)パイプ書き込み、3)内部DMA転送(Intelチップは最近これを行うことができます)である可能性があります。

内部DMAは、必要なCPU時間がゼロであるため興味深いものです(単純なmemcpyは単なるループであり、実際には時間がかかります)。したがって、データを共有する代わりにデータをコピーでき、内部DMAを使用してこれを行う場合、データを共有している場合と同じように高速になります。

ペナルティはRAMの増加ですが、アクターモデルプログラミングのようなものが機能しているという見返りがあります。これは、プログラムからセマフォを使用して共有メモリを保護する複雑さをすべて取り除く方法です。

于 2017-08-19T06:04:12.747 に答える
4

共有メモリの設定にはカーネルによる追加の作業が必要になるため、プロセスからの共有メモリ領域のアタッチ/デタッチは、通常のメモリ割り当てよりも遅くなる可能性があります(または、ベンチマークを行ったことがない場合もあります)。ただし、プロセスの仮想メモリマップに接続されると、共有メモリは、同じキャッシュラインサイズのチャンクを競合する複数のプロセッサがある場合を除いて、アクセス用の他のメモリと同じです。したがって、一般に、共有メモリはほとんどのアクセスで他のメモリと同じくらい高速である必要がありますが、そこに何を置くか、およびそれにアクセスするさまざまなスレッド/プロセスの数によっては、特定の使用パターンで速度が低下する可能性があります。

于 2013-01-24T21:34:55.730 に答える
2

共有メモリのコストは、共有メモリへの「メタ」変更の数に比例します:割り当て、割り当て解除、プロセス終了、...

メモリアクセスの数は影響しません。共有セグメントへのアクセスは、他の場所へのアクセスと同じくらい高速です。

CPUはページテーブルマッピングを実行します。物理的には、CPUはマッピングが共有されていることを認識していません。

ベストプラクティス(マッピングを変更することはめったにありません)に従うと、基本的にプロセスプライベートメモリの場合と同じパフォーマンスが得られます。

于 2013-01-24T22:29:54.973 に答える
2

共有メモリのアタッチ(shmat)とデタッチ(shmdt)のコストに加えて、アクセスも同様に高速である必要があります。言い換えれば、ハードウェアがサポートしているので高速である必要があります。アクセスごとに追加のレイヤーの形でオーバーヘッドがあってはなりません。

同期も同様に高速である必要があります。たとえば、Linuxでは、プロセスとスレッドの両方にfutexを使用できます。アトミック変数も正常に機能するはずです。

取り付け/取り外しのコストが支配的でない限り、プロセスを使用することに不利な点はありません。ただし、スレッドはより単純であり、プロセスの寿命がほとんどない場合は、オーバーヘッドのアタッチ/デタッチが問題になる可能性があります。ただし、プロセスを作成するためのコストは高くなるため、パフォーマンスが心配な場合は、とにかく、これはありそうなシナリオではありません。

最後に、この議論は興味深いかもしれません:shmatとshmdtは高価ですか?。(警告:かなり時代遅れです。それ以降、状況が変わったかどうかはわかりません。)

この関連する質問も役立つ可能性があります。IPCの共有メモリとスレッドの共有メモリの違いは何ですか。 (簡単な答え:あまりありません。)

于 2013-01-24T21:49:00.623 に答える