fork()
Perl 自身のデータ構造に関する Perl のオーバーヘッドは何ですか? 1) コード (構文ツリー) のサイズと 2) 変数/参照のデータ量は、分岐に費やされる時間に影響しますか?
4 に答える
fork
システムコールなので、Perl の質問ではありません。そのプロセスが Perl であるかどうかに関係なく、常に同じことを行います。プロセスの部分的な内部構造は気にせず、メモリの合計サイズのみが影響します。
Linux などの最新のオペレーティング システムはCOWを実装しているためfork
、通常は非常に迅速に、各プロセスでほぼ同じ値を返します。
簡単な答えは、他の人が言ったように、コード/データの量はfork()
、システムの実装によって一般的に暗示されるものを超えてパフォーマンスに影響を与えないということです。
ただし、ドキュメントに従って、perl 自体は fork を呼び出す前に開いているファイルハンドルをフラッシュします。そうです、開いている perl ファイルハンドルの数は fork() のパフォーマンスに何らかの影響を与えます。
(スレッド化された perl ビルドは、メモリ割り当てを保護する内部ミューテックスもスローします。私のシステムでは、少なくとも 5.16 未満です。このような小さな内部同期は、システムごと、および perl バージョンごとに異なる可能性があります。)
フォークすると、プロセス全体 (コードとデータ) の個別のコピーが作成されます。I/O ハンドルを除くすべてのものが作成されます。そのため、プログラムのメモリ フットプリントを増やすと (余白で) fork 操作に時間がかかります。
大量のデータと複数の子プロセスを処理するプログラムの場合、考慮すべきことの 1 つは、親プロセスのフットプリントをできるだけ小さく保ち、子プロセスの開始後にデータをロードすることです。
fork
それ自体はメモリを使用しません。親プロセスのメモリ ページは、子プロセスが共有ページに書き込もうとするまで子プロセスと共有されます。この時点で、ページのコピーが作成され、各プロセスが独自のページのコピーを持つようになります。
コードと読み取り専用データが書き込み可能なデータから分離されている場合、多くのページが常に共有されることになります。
ただし、Perl にはコードとデータの分離はありません。オペコードはデータと同じメモリ プールで作成されるだけでなく、オペコードには書き込み可能なコンポーネントがあります。これは、フォークされた子が最終的にほとんど共有されないことになることが多いことを意味します。
確実に知るにはps
、プロセスの実行中に掘り下げる必要があります。