2

問題の説明

ディスクから大きなファイルをストリーミングする必要があります。ファイルがメモリに収まるよりも大きいと仮定します。さらに、データに対して何らかの計算を行っていて、結果がメモリに収まるほど小さいと仮定します。架空の例として、200GBファイルのmd5sumを計算する必要があり、RAMの使用量を保証して計算する必要があるとします。

要約すれば:

  • 一定のスペースである必要があります
  • できるだけ速く
  • 非常に大きなファイルを想定する
  • 結果はメモリに収まります

質問

一定のスペースを使用してファイルからデータを読み取る/ストリーミングする最速の方法は何ですか?

私が持っていたアイデア

ファイルがメモリに収まるほど小さい場合、mmapPOSIXシステムでは非常に高速になりますが、残念ながらここではそうではありません。mmapファイルの連続するチャンクをバッファリングするために小さなバッファサイズで使用することにパフォーマンス上の利点はありますか?バッファをファイルの下に移動するシステムコールのオーバーヘッドがmmap利点を左右しますか、それとも、読み込んだ固定バッファを使用する必要がありfreadますか?

4

3 に答える 3

3

それが非常に高速になるかどうかはわかりませんmmap(非常に高速とは、よりも大幅に高速であると定義されていますfread)。

grep は を使用してmmapいましたが、 に戻しましたfread。その理由の 1 つは安定性でした (マップ中にファイルが縮小したり、IO エラーが発生したりすると、mmap で奇妙なことが起こります)。このページでは、その歴史の一部について説明します。

--mmapシステムのパフォーマンスを grepのオプションと比較できます。私のシステムでは、200 GB のファイルのパフォーマンスの違いは無視できますが、マイレージは異なる場合があります!

要するに、fread固定サイズのバッファで使用します。コーディングが簡単で、エラーの処理が簡単で、ほぼ確実に十分に高速です。

于 2009-12-08T00:05:43.623 に答える
0

使用している言語に応じて、特定のバッファー サイズを宣言したファイルに基づく C ライクな fread() ループには、正確にこのバッファー サイズが必要であり、それ以上でもそれ以下でもありません。

通常、4 から 128 キロバイトのバッファー サイズを選択します。これより大きなバッファーを使用しても、メリットはほとんどありません。

パフォーマンスが非常に重要で、比較的わずかな利益しか得られない (そして何かを作り直すリスクがある) 場合は、2 スレッドの実装を使用することを検討できます。一度にバッファの 1 つでシーケンシャルに計算します。この方法で、ディスク アクセスの遅延を取り除くことができます。

于 2009-12-07T23:59:37.360 に答える
0

mjv そうですね。ダブルバッファとオーバーラップ I/O を使用できます。そうすれば、クランチとディスクの読み取りを同時に行うことができます。次に、クランチをプロファイルまたはスタックショットして、可能な限り高速にします。運が良ければ I/O よりも高速になるため、I/O を一時停止することなく最高速度で実行することができます。次に、ファイルの断片化などの問題が発生します。

于 2009-12-08T13:52:26.597 に答える