43

重複の可能性:
mmap() と読み取りブロック

mmap()シーケンシャルIOよりも速いと聞きました(インターネットのどこかで読んだ) 。これは正しいです?はいの場合、なぜ速いのですか?

  • mmap()シーケンシャルに読み取っていません。
  • mmap()と同じようにディスク自体から取得するread()必要があります
  • マップされた領域はシーケンシャルではないため、DMA はありません (?)。

それで、実際にはファイルからmmap()よりも遅くなるはずですか?read()上記の私の仮定のどれが間違っていますか?

4

3 に答える 3

68

mmap() はシーケンシャル IO よりも高速であると聞きました (インターネットのどこかで読んだ)。これは正しいです?はいの場合、なぜそれが速いのですか?

それは可能です-以下にリストされている長所と短所があります。 本当に気にする理由がある場合は、常に両方をベンチマークしてください。

実際の IO 効率とは別に、アプリケーション コードが I/O を実行する必要があるタイミングを追跡し、データの処理/生成を行う方法には影響があり、パフォーマンスに非常に劇的な影響を与える場合があります。

1) mmap() が順次読み取りを行っていません。2) mmap() は、read() と同じようにディスク自体から取得する必要があります。3) マップされた領域はシーケンシャルではありません。したがって、DMA はありません (?)。

では、mmap() は実際にはファイルからの read() よりも遅いはずですか? 上記の私の仮定のどれが間違っていますか?

1)間違っています...mmap()ファイルコンテンツに対応する仮想アドレス空間の領域を割り当てます...そのアドレス空間のページがアクセスされるたびに、物理RAMが仮想アドレスをバックアップすることがわかり、対応するディスクコンテンツがそのRAMにフォールトされます. そのため、ディスクから読み取られる順序は、アクセスの順序と一致します。これは「怠惰な」I/O メカニズムです。たとえば、ディスクから読み取る巨大なハッシュ テーブルにインデックスを付ける必要がある場合は、mmapファイルにアクセスしてアクセスを開始すると、ディスク I/O がシーケンシャルに実行されないため、ファイル全体がメモリに読み込まれるまでの経過時間が長くなる可能性がありますが、その間にルックアップは成功し、依存する作業を行うことができます。ファイルの一部が実際に必要とされない場合、それらは読み取られません (ディスクとメモリ ページの粒度を考慮し、メモリ マッピングを使用する場合でも、多くの OS では、計画に関するパフォーマンス向上/メモリ効率のヒントを指定できます)。パターンにアクセスして、プロアクティブに先読みしたり、メモリに戻る可能性が低いことを知ってより積極的にメモリを解放したりできるようにします)。

2) まったく正しい

3) 「マッピングされた領域はシーケンシャルではありません」はあいまいです。メモリ マップ領域は、仮想アドレス空間で「連続」(シーケンシャル) です。上記で、ディスク I/O がシーケンシャルであることについて説明しました。それとも、何か他のことを考えていますか?とにかく、ページがフォールトインしている間、実際には DMA を使用して転送される可能性があります。

さらに、メモリ マッピングが通常の I/O よりもパフォーマンスが優れている理由は他にもあります。

  • コピーが少ない:
    • 多くの場合、OS およびライブラリ レベルのルーチンは、データがアプリケーション指定のバッファに到達する前に 1 つまたは複数のバッファを介してデータを渡します。その後、アプリケーションは動的にストレージを割り当て、I/O バッファからそのストレージにコピーして、ファイルの読み取りが完了した後にデータを使用できるようにします。
    • メモリ マッピングにより、インプレースでの使用が許可されます (ただし、強制はされません) (ポインターと場合によっては長さを記録することができます)。
      • その場でデータにアクセスし続けると、後でスワッピングが増加するリスクがあります。ファイル/メモリマップは、解析できるデータ構造よりも冗長になる可能性があるため、その中のデータのアクセスパターンは、より多くのメモリページでフォールトするまでの遅延が大きくなる可能性があります
  • メモリ マッピングは、別のバッファがいっぱいになるタイミングを気にするのではなく、アプリケーションがファイル コンテンツ全体をアクセス可能として処理できるようにすることで、アプリケーションの解析ジョブを簡素化できます。
  • アプリケーションは、任意の時点で物理 RAM にあるページの数に関する OS の知恵にさらに従い、直接アクセス ディスク キャッシュをアプリケーションと効果的に共有します。
  • 以下の好意的なコメントとして、「メモリマッピングを使用すると、通常はシステムコールの使用が少なくなります」
  • 複数のプロセスが同じファイルにアクセスしている場合、物理バッキング ページを共有できる必要があります。

これも遅くなる理由mmapです - Linus Torvald の投稿をここで読んでmmapください。

...ページテーブルゲームと障害 (および TLB ミスだけでも) のオーバーヘッドは、適切なストリーミング方法でページをコピーするコストを簡単に上回ります...

そして彼の別の投稿から:

  • 非常に顕著なセットアップと分解のコスト。そして、私は目立つことを意味します。ページテーブルをたどってすべてをきれいにアンマップするようなものです。これは、すべてのマッピングのリストを維持するための簿記です。これは、マッピングを解除した後に必要な TLB フラッシュです。

  • ページ フォールトは高くつきます。これがマッピングの作成方法であり、非常に低速です。

FWIW、これが職場で最後に発生したとき、メモリマップ入力は、freadバイナリデータベースレコードをプロプライエタリデータベースに読み取るために、約170GBのファイルを持つ64ビットLinuxで et al よりも80%高速でした。

于 2012-03-22T08:07:58.343 に答える
13
  1. mmap()プロセス間で共有できます。
  2. DMA は可能な限り使用されます。DMA は連続メモリを必要としません。多くのハイエンド カードはスキャッター ギャザー DMA をサポートしています。
  3. メモリ領域は、可能であればカーネル ブロック キャッシュと共有できます。したがって、レッサーコピーがあります。
  4. のメモリmmapはカーネルによって割り当てられ、常に整列されます。
于 2012-03-22T07:49:35.550 に答える
6

絶対的な意味での「より速い」は存在しません。制約と状況を指定する必要があります。

mmap() が順次読み取りを行っていません。

何があなたをそう思わせたのですか?マップされたメモリに実際に順番にアクセスする場合、システムは通常、その順序でページをフェッチします。

mmap() は read() と同じようにディスク自体からフェッチする必要があります

確かに、OSは時間とバッファサイズを決定します

マップされた領域はシーケンシャルではないため、DMA はありません (?)。

上記を参照

役立つのは、追加のユーザー空間バッファーが関与しないことですmmap。「読み取り」は、OS カーネルが適合すると判断した場所で、最適化できるチャンクで行われます。これは速度の点で有利かもしれませんが、まず第一に、これは使いやすいインターフェースです。

特定のセットアップ (ハードウェア、OS、使用パターン) の速度を知りたい場合は、測定する必要があります。

于 2012-03-22T07:12:01.727 に答える