1

あるプロセスが別のプロセスからフォークされたとします。つまり、fork 関数呼び出しによってプロセスを複製します。フォークはコピー オン ライト メカニズムであるため、フォークされたプロセスまたは元のプロセスがページに書き込むたびに、書き込む新しい物理ページが取得されます。私が理解したことは、フォークされたプロセスと元のプロセスの両方が実行されている場合、次のようになります。

--> フォークすると、元のプロセスとフォークされたプロセスのすべてのページに読み取り専用アクセスが与えられるため、カーネルはどのページが書き込まれたかを知ることができます。これが発生すると、カーネルは新しい物理ページを書き込みプロセスにマップし、以前のコンテンツをそれに書き込み、そのページへの書き込みアクセスを許可します。今はっきりしていないのは、フォークと元のプロセスの両方が同じページに書き込む場合、そのうちの1つが元の物理ページを保持するか(フォークする前)、または両方が新しい物理ページを取得するかです。第二に、フォークされたプロセスと元のプロセスのすべてのページに、フォーク時に読み取り専用アクセスが与えられるという私の仮定は正しいですか?

--> 各ページ フォールトが割り込みをトリガーするため、元のプロセスまたはフォークされたプロセスへの書き込みごとに実行速度が低下します。アプリケーションについて知っていて、大量の連続したメモリ ページが書き込まれることがわかっている場合、グループ内のページの 1 つが複数のページ (たとえば、ページのグループ) に書き込み許可を与える方がよいのではないでしょうか。に書かれています。これにより、ページ フォールト処理による割り込みの数が減ります。ではない?確かに、この場合、不必要にコピーを作成することがありますが、512 個のlong型の変数(ページの 4096 バイト) を書き込むよりも、割り込みの方がオーバーヘッドがはるかに大きいと思います。私の理解は正しいですか、それとも何か不足していますか?

4

3 に答える 3

1

フォークは意味的にプロセスのコピーを作成します。コピー オン ライトは、それを大幅に高速化する最適化です。最適化には、隠れたトレードオフがあることがよくあります。一部のケースは高速化されますが、他のケースは問題があります。コピーオンライトにはコストがかかりますが、コピーされたページのほとんどは実際には子によって書き込まれるわけではないため、通常は節約になることを願っています。理想的なケースでは、子は即時実行を実行します。

そのため、少数のページでページ フォールトの例外が発生します。これは、事前にすべてのページをコピーするよりも安価です。

ほとんどの「遅延評価」タイプの最適化は、この性質のものです。

100 万項目の遅延リストを完全にインスタンス化するには、100 万項目の通常のリストよりもコストがかかります。しかし、リストのコンシューマーが最初の 100 項目にしかアクセスしない場合は、レイジー リストが優先されます。

于 2012-04-18T20:14:07.857 に答える
1

私が間違っていなければ、プロセスの 1 つがページへの最初の書き込みと見なされます。複数のコアがある場合でも、ページ フォールトは順次処理されると思います。その場合、最初に捕捉されたプロセスは 2 つのプロセスのページを分離するため、2 番目のプロセスがそれに書き込むまでに、そのプロセスの書き込み可能なページがあるため、障害は発生しません。自分の。

それが完了すると、既存のページは1つのプロセスによって保持され(そして読み取り/書き込みに戻され)、別のプロセス用に1つの新しいコピーが作成されると思います。

あなたの 3 番目のポイントは、「アプリケーションについて知っているかどうか...」という 1 つの単純なポイントを中心に展開していると思います。そこに問題があります。OS はアプリケーションについて認識していません。基本的に、それが「知っている」唯一のことは、カーネル コーダーによる観察を通じて、間接的なものになります。彼らは間違いなくfork通常 が続くことを観察するexecので、間違いなく最適化するのはその場合です。はい、常にそうであるとは限りません。また、明らかに他のケースについても心配されています。ここで私が言っているのは、それらが十分に異常であるため、ほとんど労力が費やされていないと推測するということだけです。

4096 バイトのページで 512 の long についての論理または数学に従うかどうかはよくわかりません。最初にページが書き込まれると、ページが複製され、プロセス間で分離されます。その時点以降、そのページのいずれかのプロセスのコピーにさらに書き込みを行っても、それ以上のページ フォールトは発生しません (少なくとも書き込み時のコピーに関連します。ページファイル、またはその順序の何かですが、ここでは関係ありません)。

于 2012-04-18T20:20:42.313 に答える
0

fork() が COW を使用しない場合、初期コストが非常に高くなります。典型的なディスプレイを見るとtop、RSS/VSIZE の比率は非常に小さいです (例えば、典型的な vi セッションでは 2MB/56MB)。

COW を使用せずにプロセスを複製すると、膨大な量のメモリ プレッシャが発生し、実際には他のプロセスがアタッチされたページを失います (セカンダリ ストレージに移動する必要があり、後で復元する必要があります)。そして、そのページングにより、実際にはページごとに 1 ~ 2 のディスク I/O が発生します (ページが新しいかダーティな場合にのみスワップ アウトが必要であり、ページが他のプロセスによって再び参照される場合にのみスワップ インが必要になります)。

もう 1 つのポイントは粒度です。MMU が存在しなかった時代には、プロセス全体をスワップアウトしてメモリを解放する必要があり、システムが実際に 1 秒程度フリーズする原因となりました。ページごとのページ違反はより多くのトラップを引き起こしますが、これらは適切に分散されているため、プロセスは実際に物理 RAM を求めて競合することができます。予備知識がなければ、LRU スキームに勝るものはありません。

于 2012-04-18T20:47:16.390 に答える