2017-09-13 8 views
2

別の方法で質問するには、実際にはページキャッシュにある正確な物理ページに実際にアクセスするファイルをmmap()すると確認できますか?mmapはページキャッシュまたはページキャッシュのコピーに直接アクセスしますか?

私は、テストの前にページキャッシュにプリキャッシュされている400GBのデータファイルで、1TBのRAMを搭載した192コアマシンでテストを行っているので質問します(キャッシュを落としてからmd5sumファイル上に)。

最初は、基本的に同じメモリ領域を戻す(または同じメモリ領域を何らかの形で複数回マップする)という前提で、それぞれ192スレッドのファイルを別々にmmapしました。したがって、同じファイルに対する2つの異なるマッピングを使用する2つのスレッドが、両方とも同じページに直接アクセスできると仮定しました。 (明らかにそれが高いスレッド数で重要なのですけれども、のは、この例ではNUMAを無視してみましょう。)

しかし、実際に私は、各スレッドが個別にファイルをたmmapときのパフォーマンスが高いスレッド数でひどいになるだろうが分かりました。これを削除してスレッドに渡された単一のmmapを(すべてのスレッドが同じメモリ領域に直接アクセスするように)実行したところ、パフォーマンスは向上しました劇的に

それはすべて素晴らしいですが、私はなぜそれを理解しようとしています。実際にファイルをmmappingするだけで、既存のページキャッシュに直接アクセスできる場合は、マップする回数は関係ありません。すべて同じ場所に移動する必要があります。

しかし、このようなパフォーマンスコストがあるとすれば、実際には、それぞれのmmapは(おそらくページキャッシュからコピーするか、またはディスクから再度読み込むことによって)独立して冗長に配置されているように思えます。

あなたは、同じファイルをmmappingするのと比べて、同じメモリへの共有アクセスのような異なるパフォーマンスを見ていた理由についてコメントできますか?

ご協力いただきありがとうございます。

+0

これは大きな問題です。私は答えることができないと思うが、いくつかの提案をする。 1 /なぜそれをプロファイルしないのですか? perfは、ボトルネックがどこにあるのかを簡単に伝えることができます(私は願っています)。私の推測では、あなたはmmap(小さな)オーバーヘッドに当たっていますが、192スレッドではスケーリングされません。また、巨大なページを使ってみましたか? – Aissen

+0

興味深いものがすべてカーネルの深いところで起こっているので、プロファイルするのは難しいです。私のアプリケーションが知っている限り、それはRAMにアクセスしているだけです。しかし、メモリマッピング、仮想メモリ、ページキャッシュ、L3キャッシュ、NUMAノードの間では、動く部品がたくさんあります。それは私がこれを理解するためにもっと多くの作業が必要であることに同意したと言いましたが、私よりもカーネルに関する知識が豊富な人が少なくとも理論*実際に私のテストをガイドします。 – quinthar

+0

ええ、普通はperfは、適切な記号がついていれば、カーネルが時間を費やしている場所を知っています。あなたの質問に関して、私は問題の原因が何であるか分かりません。小さなマシンでそれを再現しようとしましたか? – Aissen

答えて

1

私は私の答えを見つけたと思うし、それはページのディレクトリを扱う。答えは「はい」です。同じファイルの2つのmmapped領域が同じ基本ページキャッシュデータにアクセスします。しかし、各マッピングでは、仮想ページのそれぞれを物理ページに独立してマップする必要があります。つまり、同じRAMにアクセスするためにページディレクトリに2倍のエントリが必要です。

基本的に、各mmap()は仮想メモリ内に新しい範囲を作成します。その範囲のすべてのページは物理メモリのページに対応し、そのマッピングは階層ページディレクトリに格納されます(4KBページあたり1エントリ)。したがって、大きな領域のすべてのmmap()は、ページディレクトリに膨大な数のエントリを生成します。

私の推測では、実際にそれらをすべて前面に定義していないので、mmap()は巨大なファイルであっても瞬時に呼び出すことができます。しかし時間がたつにつれて、mmapped範囲に不具合があるので、おそらく記入する時間の経過を意味するので、おそらくそれらのエントリを確立する必要があります。ページディレクトリに移入するこの余分な作業は、おそらく異なるmmapを使用するスレッドが同じmmapを共有するスレッドより遅いのです。そして、範囲をアンマップするときにカーネルがこれらのエントリをすべて消去する必要があると思います。そのため、unmmap()はとても遅いのです。

(そこ変換索引バッファもありますが、それは毎CPUだ、と私はずっとここに問題はないと思いますので、小さな。)とにかく

、再マッピング同じ領域だけで余分な追加されますように聞こえますオーバーヘッド、私は何の利益がないようです。

関連する問題