2013-02-11 12 views
7

Linux 64ビット(Amazon EC2インスタンスなど)では、大きなバイナリファイルをメモリにロードする必要があります。最速の方法は何ですか?C++では、大きなバイナリ(1GB〜4GB)ファイルをメモリにロードする最も速い方法は何ですか?

  • はifstream
  • のfread
  • POSIXオープン
  • POSIXのMMAP(実際にパフォーマンスが痛いこれは、メモリにファイル全体をロードしません)
  • 他の何か?

また、ノードはこの実行可能ファイルを2回目に起動することもあれば起動しないこともあるので、後続の試行でファイルがさらに高速にロードされた場合に役立ちます。いくつかの事前ロードステップが機能するかもしれません。

+2

どのようにファイルにアクセスしますか?あなたはそれを使用する前に、メモリ内のすべてのファイルを必要としますか?あなたは読み書きしますか、またはちょうど読みますか? –

+0

最初の4つのオプションのベンチマークで始めるのはなぜですか?私はあなたが非常に簡単にそれを測定することができ、とにかくそれを行う必要があると思う:それはパフォーマンスになると、あなたは盲目的に何も測定せずに信用すべきではありません。 –

+0

実際にmmapを使用するのが実際に遅いのですか?あなたのプロセスのメモリは、ファイルの内容と同じようにスワップアウトすることができます。また、mmapに対してMAP_POPULATEフラグを試して、マッピングのページを事前にフォールトすることもできます。 –

答えて

7

時間はディスクI/Oによって支配されるため、使用するAPIはディスクの仕組みについて考えるほど重要ではありません。ディスク(回転メディア)にランダムにアクセスすると、3〜9ミリ秒の時間がかかります。ディスクがストリーミングされると、約128 MB /秒が維持されます。 SATAリンクまたはPCIeバスは、それよりもはるかに高い帯域幅(600〜2000 MB /秒)を持っています。 Linuxにはディスク上にページのコピーを保存するページキャッシュがあります。そのため、RAMに十分なRAMがあれば、ランダムにデータにアクセスしてもその後の試行は高速になります。したがって、アドバイスは一度に大きなブロックで読み込まれます。実際に初期ロードを高速化したい場合は、mmapを使用してファイル全体(1GB〜4GB)をマップし、各ページの第1バイトを順番に読み取るヘルパースレッドを使用できます。あなたはdisk drive performance characteristics here.

の詳細を読むことができ

あなたは、上記の情報が与えられpage cache here.

1

の詳細を読むことができ、私はmmapが良い候補であると思います。私が言うことにはいくつかの理由があります: 1.実際にその部分が必要になるまで、実際にファイルをロードせずにWHOLEファイルを提供します。これは高速読み込みの利点ですが、最終的にすべてのバイトを処理した場合[またはファイルの4KBセクションごとに触れた場合]、大きな違いはありません。 2. mmapは、ディスクからページにデータをコピーします。これは、私のテストでは、freadまたはreadをLinuxで使用するよりも効率的です(かなり大きな読み取りに対してfreadreadの違いは無視しても差し支えありません)。FILE C.しかし、私の経験では、かなりのオーバーヘッドがありました[これまで何度もさまざまな形で試してみました]

いつもと同じように、ベンチマークは常にインターネット上で尋ねています。あなたの状況では適切ではないと指摘されているように、コードが十分に良好であれば、コードのオーバーヘッドは、ディスクがデータを配信できるスピードに比べて桁外れです。たとえ並列(SSD ?)ディスクなど、最終的にディスク転送sボトルネックがどこになるのだろうか。その時点でできることは、可能な限りオーバーヘッドを最小限に抑え、ディスクにデータが配信されたらできるだけ早くアプリケーションにデータを取得することです。

「1秒あたりのバイト数」の良い基準は、ファイルを書き込むdd if=/dev/zero of=somefile bs=4K count=1Mを使用することです。その場合、ディスクからどれくらいの読みやすさを確認するには、dd if=somefile of=/dev/null bs=4Kにします。

1

mmapMAP_POPULATEフラグで試してみてください。私はあなたがこれをもっと速く行うことができるとは思わない。

関連する問題