18

ネットワークから大量のデータ (さまざまなサイズの断片) を受信し、それらを処理してメモリに書き込むプログラムを作成しています。一部のデータは非常に大きくなる可能性があるため、現在のアプローチでは、使用するバッファー サイズを制限しています。ピースが最大バッファ サイズよりも大きい場合は、データを一時ファイルに書き込み、後でファイルをチャンク単位で読み取って処理し、永続的に保存します。

これを改善できないか悩んでいます。私はしばらくの間 mmap について読んできましたが、それが役立つかどうかは 100% 確信が持てません。私の考えは、一時ファイルの読み取りに mmap を使用することです。これは何らかの形で役立ちますか?私が主に懸念しているのは、ときどき大量のデータがメイン メモリをいっぱいにして、他のすべてがスワップ アウトされないようにすることです。

また、一時ファイルを使用したアプローチは有用だと思いますか? 私はそれをしなければならないのでしょうか、それとも Linux のメモリ マネージャーが私のために仕事をしてくれると信頼すべきでしょうか? それとも、まったく別のことをする必要がありますか?

4

3 に答える 3

16

Mmap はいくつかの点で役立ちます。いくつかの仮説的な例で説明します。

最初に: メモリが不足していて、100MB の malloc メモリ チャンクを持つアプリケーションがその 50% をスワップ アウトしたとします。つまり、OS はスワップファイルに 50MB を書き込む必要がありました。それを読み返す必要があります.50MBのスワップファイルを書き込んで占有し、再度読み戻します.

メモリが mmap されたばかりの場合、オペレーティング システムはその情報をスワップファイルに書き込まず (そのデータがファイル自体と同一であることを認識しているため)、代わりに 50MB の情報をスクラッチします (再び:あなたが今のところ何も書いていないと仮定します)そしてそれはそれです。そのメモリを再度読み取る必要がある場合、OS はスワップファイルからではなく、mmap した元のファイルからコンテンツをフェッチするため、他のプログラムが 50MB のスワップを必要とする場合、それらは利用可能です。また、スワップファイル操作によるオーバーヘッドはまったくありません。

100MB のデータ チャンクを読み取ったとします。ヘッダー データの最初の 1MB によると、必要な情報はオフセット 75MB にあるため、1 ~ 74.9MB の間は何も必要ありません。コードを単純にするためだけに読んでいます。mmap を使用すると、実際にアクセスしたデータ (丸められた 4kb、またはほとんどが 4kb である OS ページ サイズ) のみを読み取るため、最初と 75 MB のみを読み取ることになります。ファイルの mmap よりも、ディスクの読み取りを回避するためのより簡単で効果的な方法を作成するのは非常に難しいと思います。何らかの理由でオフセット 37MB のデータが必要な場合は、そのまま使用できます。ファイル全体がメモリ内でアクセスできるため、再度 mmap する必要はありません (もちろん、プロセスのメモリ空間によって制限されます)。

mmap されたすべてのファイルは、swapfile によってではなく、それ自体によってバックアップされます。swapfile は、バックアップするファイルを持たないデータを許可するように作成されます。これは通常、データ malloc されるか、ファイルによってバックアップされるデータです。 、しかし、それは変更されており、プログラムが実際に msync 呼び出しを介して OS にそうするように指示する前に、[できません/できない] それに書き戻されます。

メモリ内のファイル全体をマップする必要はないことに注意してください。任意の場所 (6 番目の引数 - 「off_t オフセット」) から開始して任意の量 (2 番目の引数は「size_t 長さ」) をマップできますが、ファイルが可能性が高い場合を除きます。システムが64MBの物理メモリしかパックしていなくても、1GBのデータを恐れることなく安全にマップできますが、それは読み取り用です。書き込みを計画している場合は、より保守的になり、必要なものだけをマップする必要があります.

ファイルのマッピングは、コードをより単純にするのに役立ちます (メモリ上にファイルの内容が既にあり、使用する準備ができており、匿名メモリではないため、メモリのオーバーヘッドがはるかに少なくなります)、より高速になります (プログラムがアクセスしたデータのみを読み取ることができます)。

于 2012-04-25T02:14:55.743 に答える
2

大きなファイルでの mmap の主な利点は、2 つ以上のファイル間で同じメモリ マッピングを共有MAP_SHAREDできることです。

しかし、私の知る限り、mmap はファイル全体をメモリにマップします (ここでは、物理メモリ + スワップ スペースよりも大きなファイルで mmap が失敗する例を見つけることができます)。そのため、単一のプロセスからファイルにアクセスする場合、物理的なメモリ消費。

于 2012-04-24T18:48:09.010 に答える
1

mmapは、すべてのデータを同時にメモリに格納する必要はないと思います。ページキャッシュを使用して、最近使用したページをメモリに保持し、残りをディスクに保持します。

一度に1つのチャンクを読み取る場合、一時ファイルを使用してもおそらく役に立ちませんが、複数のスレッド、プロセス、またはselect / pollを使用して複数のチャンクを同時に読み取る場合は、役立つ可能性があります。

于 2012-04-24T22:49:09.883 に答える