web-dev-qa-db-ja.com

Cでのmallocとmmap

2つのプログラムを作成しました。1つはmallocを使用し、もう1つはmmapを使用します。 mmapを使用した場合の実行時間は、mallocを使用した場合よりもはるかに短くなります。

たとえば、mmapを使用しているときは、システムへの読み取り/書き込み呼び出しを回避することを知っています。そして、メモリアクセスが少なくなります。

しかし、mmapよりもmallocを使用する場合に利点がある理由は他にありますか?

どうもありがとう

40
Peter

ファイルからデータを読み取るためにmmapとmallocを使用することを参照していると思います。その場合、あなたはほとんど要点を得ました:

  • fread/fwriteを使用すると、OSを何度も呼び出す必要があります。
  • mmapを使用すると、1回の操作でファイル全体にアクセスできます。 OSがファイルを一度に1つずつマッピングするため、これは完全には当てはまりません memory page ですが、それでもずっと高速です。
14
Anton

mmapは実際にはファイルをメモリにロードしないため、ロードは速くなりますが、編集は遅くなります。

もう1つのポイントは、mmapはメモリを使用しないが、アドレス空間を占有することです。 64ビットマシンでは、ほとんどのメモリアドレススペースにメモリがないため、mallocを実行したくない巨大なファイル、たとえば5GBをロードできます。

13

一般的な考えとは逆に、mmapは確かにmallocに似たメモリ割り当て関数です。

mmapedファイルはその1つの用途です。ファイル記述子として-1を渡して、メモリ割り当て関数として使用できます。

したがって、一般的な使用法は、小さなオブジェクトにはmallocを使用し、大きなオブジェクトにはmmapを使用することです。

これは良い戦略です。

alloca()を使用して、関数スコープのみの変数を作成します。

10
user410034

Mallocとmmapはどちらも遅い場合があります。それは主に使用パターンに依存します:

mmap:カーネルページングサブシステムはページサイズ単位で機能します。つまり、ファイルからページ全体を読み取り、繰り返しそれを行いたい場合(ローカライズが適切)、mmapで問題ありません。逆に、5 Gbのファイルをマップして分散アクセスを行うと、カーネルスワップページが大量に出入りします。実際のI/Oに加えて、ページの管理には時間がかかります。レイテンシについて懸念がある場合は、このアクセスパターンを避けてください。Linuxページの再利用メカニズムがバーストする傾向があり、顕著な遅延が発生し、キャッシュポイズニングによって他のプロセスの速度が低下するためです。

malloc:ページサイズ単位ではないメモリが必要な場合は問題ありません。しかし、mlock()のようなことを正気に行うことはできません。 I/Oに関しては、速度はその方法に大きく依存します。 fread/fwriteは、ページの裏側をマップするか、ユーザー空間でバッファリングを行います。ローカライズされたアクセスはかなり高速になります。読み取り/書き込みはカーネルを直接経由するため、小さな分散アクセスではキャッシュミスのためにI/Oが発生しますが、カーネルからユーザースペースに転送される実際のデータはわずかに少なくなります。それが測定可能かどうかはわかりません。

Mlock()を実行しない限り、ユーザーページはいつでもスワップアウト/書き戻されます。これも時間がかかります。したがって、メモリが少ないシステムでは、最もメモリが少ないマップが優先されます。 Linuxカーネルでは、未使用のページがI/Oのキャッシュに使用されるため、すべてのシステムのメモリが少なすぎます。メモリの使用やI/Oがバースト的である場合、カーネルがそれらを使用できるようになるまでにかなりの時間がかかる場合があります。

9
prostatanus

mmapは実際にはファイルを読み取りません。それをアドレス空間にマッピングするだけです。これが非常に高速な理由です。実際にアドレス空間のその領域にアクセスするまで、ディスクI/Oはありません。

mallocはアドレス空間のメモリへの単なるマッピングです

2
joemoe