GNU/Linux >> Linux の 問題 >  >> Linux

ファイルのメモリ マッピングにより、標準の I/O システム コールよりもパフォーマンスが大幅に向上するのはなぜですか?

ファイルを直接メモリ マッピングすると、read() で発生するバッファのコピーが回避されます と write() 呼び出します。 read() への呼び出し と write() データが格納されるプロセスのアドレス空間にバッファへのポインタを含めます。カーネルは、これらの場所との間でデータをコピーする必要があります。 mmap() の使用 ファイルをプロセスのアドレス空間にマップするため、プロセスはファイルを直接アドレス指定でき、コピーは必要ありません。

ファイルが最初の mmap() でメモリにロードされている場合、最初の呼び出しの後にメモリ マップされたファイルにアクセスするときに、システム コールのオーバーヘッドもありません。 .マップされたファイルのページがメモリ内にない場合、アクセスによってエラーが発生し、カーネルがページをメモリにロードする必要があります。 read() で大きなブロックを読み取る mmap() よりも高速になる可能性があります このような場合、mmap() の場合 ファイルを読み取るためにかなりの数のエラーが発生します。 (madvise() で事前にカーネルに通知することが可能です) カーネルがアクセス前に事前にページをロードできるようにします)。

詳細については、スタック オーバーフローに関する関連する質問があります:mmap() vs. reading blocks


まず、ほとんどの IO 操作では、基盤となるストレージ ハードウェアの特性がパフォーマンスを支配します。 29 台の S-L-O-W 5400 rpm SATA ディスクの不適切に構成された RAID5 アレイは、ブロック サイズが一致せず、ファイル システムが正しく配置されていない S/W RAID を使用する低速でメモリが不足しているシステムでは、適切に構成されて配置されている場合に比べてパフォーマンスが低下します。どんなソフトウェア チューニングを試しても、高性能コントローラーで SSD RAID 1+0 を実現できます。

でも唯一の方法は mmap() 同じデータを複数回読み取ると、大幅に高速になる可能性がありますおよび メモリ不足のため、読み取ったデータは次の読み取りまでページ アウトされません。

メモリ マップの手順:

<オール>
  • 仮想マッピングを作成するためのシステム コール - 非常に高価
  • プロセスが初めてメモリにアクセスし、ページ フォールトを引き起こします - コストがかかります (ページ アウトされた場合は繰り返す必要がある場合があります)
  • プロセスが実際にメモリを読み取る
  • プロセスがステップ 2 と 3 を読み取りデータのビットごとに 1 回だけ実行する場合、またはメモリ不足のためにデータがメモリから削除される場合、mmap() 遅くなります。

    read() 手順:

    <オール>
  • システム コールは、ディスクからページ キャッシュにデータをコピーします (ページ フォールトの場合もそうでない場合もあり、データが既にページ キャッシュに存在する可能性があり、これがスキップされる可能性があります)
  • ページ キャッシュからプロセス メモリにコピーされたデータ (ページ フォールトの場合とない場合があります)
  • メモリ マッピングは、ページ キャッシュからプロセス メモリへの余分なコピーがあるため、パフォーマンスの点でこれを上回るだけです。しかし、メモリのページ (またはそれ以下) の単なるコピーを複数回実行して、マッピングのセットアップのコストを抑える必要があります (おそらく)。回数はシステムによって異なります。メモリ帯域幅、システム全体の使用状況、すべて。たとえば、マッピングを設定するためにカーネルのメモリ管理に費やされた時間が他のプロセスによって使用されていない場合、マッピングを作成するコストは実際にはそれほど高くありません。逆に、多くの仮想メモリ マッピングの作成/破棄 (つまり、多くの短命のプロセス) を含むシステム上に多くの処理がある場合、メモリ マップド IO の影響が大きくなる可能性があります。

    次に read() です 直接 IO を使用:

    <オール>
  • ディスクからプロセス メモリ空間に読み込むためのシステム コール。 (ページ フォールトが発生する場合と発生しない場合があります)
  • ダイレクト IO 読み取りは、パフォーマンスの面で打ち負かすことはほぼ不可能です。ただし、パフォーマンスを最大化するには、IO パターンをハードウェアに合わせて調整する必要があります。

    データの読み取りによって、プロセスが読み取りに使用しているバッファーのページ フォールトが発生するかどうかは、プロセスがほぼ制御できることに注意してください。

    では、メモリ マップト ファイルへのアクセスは高速ですか?そうかもしれないし、そうでないかもしれない。

    アクセス パターンによって異なります。 ハードウェアおよび IO パス内の他のすべてのものと一緒に。

    4 GB の RAM を搭載したマシンで 30 GB のビデオ ファイルをストリーミングしていて、戻ってデータを読み直さない場合、ファイルのメモリ マッピングはおそらく最悪です。

    逆に、処理中に何十億回もランダムにアクセスするデータ用の 100 MB ルックアップ テーブルと、ファイルが決してページ アウトされない十分なメモリがある場合、メモリ マッピングは他のすべてのアクセス方法を破壊します。

    メモリ マップト ファイルの大きな利点の 1 つ

    メモリ マッピング ファイルには、他の形式の IO よりも大きな利点があります。つまり、コードが単純です。ファイルがメモリ内にあるかのようにアクセスする単純さを超えるのは本当に難しいことです。また、ほとんどの場合、ファイルのメモリ マッピングと個別の IO 操作のパフォーマンスの違いはそれほど大きくありません。


    Linux
    1. Linux I / O(入力/出力)リダイレクトの仕組みの基本を学ぶ

    2. Linux – Ntfs論理ボリューム上のファイルの作成日を取得する方法は?

    3. コマンドSed‘1!g; h; $!d’は、ファイルの内容をどのように逆にしますか?

    1. stat コマンドはファイルのブロックをどのように計算しますか?

    2. Linux カーネルは __init 呼び出しの順序をどのように決定しますか?

    3. system() の出力をファイルにリダイレクトする方法は?

    1. tcpdump でファイルに書き込み、標準出力に適切なデータを出力するにはどうすればよいですか?

    2. カーネルはどれくらいの RAM を使用しますか?

    3. ファイル システムを持たないすべてのディスクをキャプチャする方法