mmap/read + BZ2_bzDecompress を使用して、大きなファイル (29GB) を順次解凍しています。これは、圧縮されていない xml データを解析する必要があるが、必要なのはそのほんの一部であり、ファイル全体 (400GB の非圧縮) を圧縮解除してから解析するよりも、順次実行する方が効率的であるように思われたためです。興味深いことに、すでに解凍部分は非常に遅いです。シェル コマンド bzip2 は 1 秒あたり 52MB を少し超える速度で実行できますが (いくつかの実行を使用しtimeout 10 bzip2 -c -k -d input.bz2 > output
、生成されたファイル サイズを 10 で割った値です)、私のプログラムは 2MB/s でさえ実行できません。数秒後に 1.2MB/s まで遅くなります
処理しようとしているファイルは複数の bz2 ストリームを使用しているため、 をチェックしBZ2_bzDecompress
てBZ_STREAM_END
います。それが発生した場合は、ファイルが完全に処理されていない場合に備えて、次のストリームで再開します。私もなしで試しましたが、何も変わりませんでした(そして、ドキュメントでは、複数のストリームを正しく処理する方法を実際に見ることはできません)BZ2_bzDecompressEnd( strm );
BZ2_bzDecompressInit( strm, 0, 0 )
BZ2_bzDecompressEnd
ファイルは以前にmmapされていましたが、フラグのさまざまな組み合わせも試しました.現在MAP_RDONLY
、 madviseを使用しています(戻り値をチェックしていますが、madviseは問題を報告しません.Linuxカーネル3.2x debianを使用していますhugepage をサポートするセットアップ)MAP_PRIVATE
MADV_SEQUENTIAL | MADV_WILLNEED | MADV_HUGEPAGE
プロファイリングの際、速度を測定するためのいくつかのカウンターと、n回の反復ごとに1回に制限されたprintf以外は何も実行されていないことを確認しました. また、これは、他のすべてのコアがアイドル状態の最新のマルチコア サーバー プロセッサ上にあり、仮想化されていないベア メタルです。
私が間違っている可能性がある/パフォーマンスを向上させるために何をすべきかについてのアイデアはありますか?
更新: James Chong の提案のおかげで、 と「交換」mmap()
してみread()
ましたが、速度は同じです。だから、それmmap()
は問題ではないようです(それ、または根本的な問題mmap()
をread()
共有しています)
更新 2: おそらく bzDecompressInit/bzDecompressEnd で行われた malloc/free 呼び出しが原因ではないかと考えて、bz_stream 構造体の bzalloc/bzfree をカスタム実装に設定しました。設定します (不透明パラメーター = strm.opaque によって渡されます)。完全に正常に動作しますが、やはり速度は向上しませんでした。
更新 3: read() の代わりに fread() も試しましたが、それでも速度は変わりません。また、さまざまな量の読み取りバイトと解凍データバッファーのサイズを試しましたが、変化はありませんでした。
更新 4: mmap() だけを使用してシーケンシャル読み取りで約 120MB/秒に近い速度を達成できたので、読み取り速度はまったく問題ではありません。