web-dev-qa-db-ja.com

mmap()がシーケンシャルIOより速いのはなぜですか?

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

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

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

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

41
Lunar Mushrooms

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

それはあることができます-以下にリストされている賛否があります。 本当に気にする理由があるときは、常に両方をベンチマークしてください

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

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

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

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

2)絶対に正しい

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

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

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

mmapが遅くなる理由もあります。LinusTorvaldの ここに投稿 を読み、mmapについて説明してください。

...ページテーブルゲームとフォールト(およびTLBミスのみ)のオーバーヘッドは、ニースストリーミング方式でページをコピーするコストよりも簡単に多くなります...

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

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

  • ページ違反は高価です。これがマッピングの入力方法であり、非常に低速です。

FWIW、これが仕事で私に最後に発生したとき、メモリマップされた入力は、バイナリデータベースレコードを独自のデータベースに読み込むためのfread他よりも80%高速でした。

58
Tony Delroy
  1. mmap()はプロセス間で共有できます。
  2. DMAは可能な限り使用されます。 DMAは連続したメモリを必要としません-多くのハイエンドカードはスキャッターギャザーDMAをサポートしています。
  3. メモリ領域は、可能であればカーネルブロックキャッシュと共有できます。したがって、賃貸人のコピーがあります。
  4. mmapのメモリはカーネルによって割り当てられ、常に調整されます。
10
J-16 SDiZ

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

mmap()が順番に読み取っていません。

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

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

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

マップされた領域はシーケンシャルではありません-したがって、DMA(?).

上記を参照

mmapが役立つのは、余分なユーザースペースバッファーが含まれていないということです。「読み取り」は、OSカーネルが適合していると見なされ、最適化できるチャンクで行われます。このmayは速度の点で有利ですが、まず第一に、これは使いやすいインターフェースにすぎません。

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

6
Jens Gustedt