mmap
の動作が異なります。これは予期しており、プログラムのアクセスパターンに適応しています。また、特定のポリシーをmadvise
で設定して、さらに細かく調整することもできます。デマンドページング環境でどのようにmmap
作品のはるかに徹底的な議論については
、ここに私の答えを参照してください。Which segments are affected by a copy-on-write?それはまたmmap
mmap
の使用について話すようにexecve
らを経由して、プログラムの実行の生命線です。 al。だから、それは速いと賭けることができます。助言として、malloc
が実際に匿名を使用していることは皮肉なことですmmap
。
しかし、ここでの議論のために、特に、mmap
でmalloc
とread(2)
をやっmmap
対を持つファイルは、「バッキングストア」(すなわちページング・ディスク)を注意し、メモリ領域のバッキングストアがありますファイルそのもの。このエリアは、ページをカーネルのファイルシステムのバッファページに直接マップします[彼らは長い間統一されています]。したがって、read(2)
の場合のように、カーネルファイルシステムのバッファページからアプリケーションページへの無駄なコピーは必要ありません。
malloc/read
を実行すると、上記のページが残りますが、malloc'ed領域にページング/スワップディスクのバッキングストアが追加されました。したがって、の場合と同じように、が2回、と同じページバッファを使用します。私が言及したように、データが読み取られたときにその領域にコピーされなければならない。
また、大量の読み込みを実行すると、パフォーマンスが最適ではありません。推奨サイズは、チャンク[ファイルシステムに依存]で約64KBです。
大きな読み込みを実行すると、プログラムは完了するまで開始できません。ファイルのサイズが物理メモリより大きい場合、システムはmalloc領域を読み込み、ページングディスクの前のページをフラッシュすることを無駄に開始し、ファイル全体が完全になるまでファイルの終わり近くのスペースを確保します読み込みます。
つまり、この大きな先読みが発生している間、アプリケーションは[何もしません]と待機しています。 60GBのファイルの場合、起動時間はであり、目立つのはです。
ファイルがの場合は、実際にはと十分な大きさであれば、ページングディスクの空き容量がなくなる(つまり、NULLが返されるmalloc
)。
mmap
の場合、このような問題はありません。ファイルをマップするときに、すぐにを使用して開始することができます。それは、エリアのバッキングストアから要求に応じて「フォールトイン」します(ファイルシステム内のファイルです)。そして、もしあなたが1 TBのファイルを持っていれば、mmap
はそれをうまく処理します。
また、madvise(2)
とposix_madvise(2)
を使用してページ単位で、またはファイル全体を含む任意のページ範囲でマッピングポリシーを制御できます。 madvise
syscallは比較的軽量ですので、たくさん使っても問題ありません。これはヒントですが、アプリケーションを遅らせるI/Oは行いません。 I/Oがヒントのために先読みされ始めると、バックグラウンドアクティビティとしてカーネルによって実行されます。
システムに、特定のページがすぐに必要になることを伝えることさえできます[システムはこれをプリフェッチするヒントとしてこれを使用します]。または、ページがもはや必要でないことをシステムに伝えることができます[システムはページバッファメモリ]。
ファイル全体に対して「順次アクセス」のようなことを言うことができます。これは、システムが先読みを自動的に行うことを知っていることと、もはや不要になったページのリリースを知ることを意味しますを実行すると、特定のカーネルFSページバッファが不要になったことをシステムに伝える方法がありません。物理的なRAMがいっぱいになるまで[または一定の制限を超えて]メモリシステム全体に圧力が加わります。
実際には、read
を使用して、アプリケーションがファイルの別の部分または別のファイルに移動した後、FSバッファに使用されるメモリの使用量が長く続くことがわかりました。実際、I/O集約型のアプリケーションでは、無関係な[アイドル]プロセスがページを盗み出してページングディスクに流すようにするために、非常に多くのバッファを使います。 I/Oアプリケーションを停止すると、firefoxが自分自身をページングして再び反応するようになるまでに数分かかりました。
私は定期的な読み取りとmmapのためのいくつかの広範なベンチマークを行いました。それらから、mmapは特定のアプリケーションの速度を向上させることができます。
ここに私の答えを参照してください:私はこれをしなかったread line by line in the most efficient way *platform specific*
前に、私は、mmapの給付の懐疑的だったが、ベンチマークはmmapのが勝者であることを示しています。
read(2)
(速度用)とfgets
を実行している場合は、ある行が読み取りバッファの境界(つまり、最後の50文字バッファは80文字の行の最初の50バイトを持つ)。そこに上記に投稿するにはあまりにも大きかった私のベンチマークプログラムと結果の以降のバージョンにペーストビンへの別のリンクがSOベンチマークという答えであり、様々なmadvise
オプション
を比較することは、このリンク先のページ内のコメントで
は
注意、
それは* *読んでスピードアップしません。同じ量のブロックをディスクから読み込む必要があります。プログラマの観点からすると(時には)より便利になります。そして、mmapはメモリの塊を割り当てず、*アドレス空間*を割り当て、実際のデータは*参照された後に*フォールトされます。 – wildplasser