12

さまざまな種類のメッセージを読み取ってカウントし、10 GB のテキスト ファイル ( FIXエンジン ログなど) でいくつかの統計を実行する必要があります。Linux、32 ビット、4 CPU、Intel、Perl でのコーディングを使用していますが、言語はそれほど重要ではありません。

Tim Bray の WideFinder プロジェクトで興味深いヒントを見つけました。ただし、メモリ マッピングの使用は、32 ビット アーキテクチャによって本質的に制限されることがわかっています。

複数のプロセスを使用してみましたが、4 つの CPU で 4 つのプロセスを使用してファイルを並列処理すると、より高速に動作するようです。マルチスレッドを追加すると、おそらくコンテキスト切り替えのコストが原因で速度が低下します。スレッドプールのサイズを変更してみましたが、それでも単純なマルチプロセス版より遅いです。

メモリ マッピング部分はあまり安定していません。2 GB のファイルで 80 秒かかることもあれば、7 秒かかることもあります。とにかく、Mmap は 32 ビット アーキテクチャで 4 GB を超えて拡張することはできません。

Perl のIPC::MmapSys::Mmapを試しました。Map-Reduce も調べましたが、問題は実際には I/O バウンドであり、処理自体は十分に高速です。

そこで、バッファリングのサイズやタイプなどを調整して、基本的な I/O を最適化することにしました。

この問題が任意の言語/プラットフォームで効率的に解決された既存のプロジェクトを知っている人は、有用なリンクを示したり、方向性を提案したりできますか?

4

13 に答える 13

9

ほとんどの場合、CPUバウンドではなくI / Oバウンドになるため、通常のPerl I / Oを介してこのファイルを読み取り、シングルスレッドで処理します。単一のCPU作業よりも多くのI/Oを実行できることが証明されない限り、それ以上の時間を無駄にしないでください。とにかく、あなたは尋ねるべきです:なぜ地球上でこれは1つの巨大なファイルにあるのですか?なぜ彼らはそれを生成するときにそれを合理的な方法で分割しないのですか?それは仕事の価値がはるかに大きいでしょう。次に、それを別々のI / Oチャネルに配置し、より多くのCPUを使用できます(ある種のRAID 0またはNASなどを使用しない場合)。

測定、仮定しないでください。各テストの前にキャッシュをフラッシュすることを忘れないでください。シリアル化されたI/Oは、ランダムよりもはるかに高速であることを忘れないでください。

于 2009-08-29T22:23:32.587 に答える
4

これはすべて、いつ、どのような前処理を実行できるかによって異なります。一部のシステムでは、このような大きなテキスト ファイルを gzip して、元のサイズの 1/5 から 1/7 に縮小しています。これを可能にする理由の 1 つは、これらのファイルを作成してから数時間後まで処理する必要がなく、作成時にはマシンに他の負荷が実際にないことです。

それらの処理は、多かれ少なかれ zcat thesefiles | の方法で行われます。ourprocessing.(カスタムメイドのzcatを使用しても、UNIXソケットで行われます)。CPU 時間をディスク I/O 時間と交換し、それだけの価値のあるシステムを提供します。もちろん、これを特定のシステムにとって非常に貧弱な設計にする可能性のある多くの変数があります。

于 2009-08-29T21:29:41.197 に答える
3

あなたのファイルの内容についてもっと知りたいのですが、それがテキストであること以外は知りません。これは優れた MapReduce のような問題のように思えます。

PS、ファイルの最速の読み取りは線形読み取りです。cat file > /dev/nullファイルを読み取ることができる速度である必要があります。

于 2009-08-28T22:44:02.120 に答える
3

このフォーラムのスレッドを既に読んでいるかもしれませんが、そうでない場合:

http://www.perlmonks.org/?node_id=512221

Perl を使用して 1 行ずつ実行する方法が説明されており、ユーザーは Perl には十分な機能があると考えているようです。

ああ、RAID アレイからファイルを処理することは可能ですか? ミラー化されたディスクが複数ある場合は、読み取り速度を向上させることができます。ディスク リソースの競合により、マルチスレッドの試行が機能しない場合があります。

幸運を祈ります。

于 2009-08-28T22:25:25.280 に答える
2

ファイルをストリーミングして、興味深い結果をセカンダリ ファイルにフィルタリングすることを考えたことはありますか? (扱いやすいサイズのファイルになるまで繰り返します)。

于 2009-08-28T22:20:21.373 に答える
1

ファイルを1回解析し、1行ずつ読み取ります。結果をまともなデータベースのテーブルに入れます。必要な数のクエリを実行します。新しい着信データを定期的に獣に与えます。

10 Gbファイルの操作、(ローカルの場合でも)ネットワークを介した転送、複雑なソリューションの探索など、すべてに時間がかかることを認識してください。

于 2009-08-29T13:37:40.983 に答える
1

うーん、しかし、C の read() コマンドの何が問題なのですか? 通常は 2GB の制限があるため、5 回連続して呼び出すだけです。それはかなり速いはずです。

于 2009-09-23T04:25:34.640 に答える
1

基本的に「分割統治」が必要です。コンピュータのネットワークがある場合は、10G ファイルをできるだけ多くのクライアント PC にコピーし、各クライアント PC にファイルのオフセットを読み取らせます。追加のボーナスとして、分散読み取りに加えてマルチスレッドを実装する各 PC を入手してください。

于 2009-08-28T22:51:05.600 に答える
1

I/O バウンドで、ファイルが 1 つのディスク上にある場合、やるべきことはあまりありません。ディスクからデータを取得する最も速い方法は、ファイル全体に対する単純なシングル スレッド リニア スキャンです。大きなバッファサイズを使用すると、少し役立つ場合があります。

ファイルのライターに複数のディスク/マシンにまたがってストライプするよう説得できる場合は、リーダーをマルチスレッド化することを検討できます (読み取りヘッドごとに 1 つのスレッド、各スレッドが単一のストライプからデータを読み取ります)。

于 2009-09-28T21:23:26.297 に答える
1

64 ビット Linux に移行して FIX の読み取り速度を上げた同僚がいます。価値のあるものなら、ちょっとした現金を投じて、より洗練されたハードウェアを手に入れましょう。

于 2009-08-29T21:21:27.610 に答える
1

プラットフォームと言語は関係ないと言ったので...

ソース メディアが許す限り高速な安定したパフォーマンスが必要な場合、これを Windows で実行できる唯一の方法は、OS バッファを使用せずにアラインされたシーケンシャル リードをオーバーラップさせることです。おそらく、2 つまたは 3 つのバッファーで数 GB/秒に達する可能性があります。それを超えると、コピーを避けるためにリングバッファー (1 つのライター、1 つ以上のリーダー) が必要になる場合があります。正確な実装は、ドライバー/API によって異なります。IOを処理するスレッド(カーネルモードとユーザーモードの両方)でメモリのコピーが行われている場合、明らかに大きなバッファがコピーされ、IOを実行するよりも多くの時間が無駄になります。そのため、最適なバッファ サイズはファームウェアとドライバによって異なります。Windows で試すのに適した値は、ディスク IO の 32 KB の倍数です。Windows ファイルのバッファリング、メモリ マッピング、およびそれらすべてがオーバーヘッドを追加します。ランダム アクセス方式で同じデータのいずれか (または両方) の複数の読み取りを行う場合にのみ有効です。そのため、大きなファイルを一度に順番に読み取る場合、OS が何かをバッファリングしたり、memcpy を実行したりしたくありません。C# を使用している場合、マーシャリングのために OS を呼び出すことにもペナルティがあるため、C++/CLI を使用しない限り、相互運用コードを少し最適化する必要がある場合があります。

ハードウェアを問題に投げ込むことを好む人もいますが、お金よりも時間があれば、シナリオによっては、1000 台のエンタープライズ価格のコンピューターよりも 1 台のコンシューマー レベルのコンピューターで 100 倍から 1000 倍優れたパフォーマンスを発揮するように最適化することが可能です。その理由は、処理も遅延の影響を受けやすい場合、2 つのコアを使用する以上に遅延が増える可能性があるためです。これが、ドライバーがギガバイト/秒をプッシュできるのに、エンタープライズ ソフトウェアがすべて完了するまでにメガバイト/秒でスタックする理由です。レポート、ビジネスロジック、およびそのようなエンタープライズソフトウェアが行うものは、80年代にゲームを書いていたように書かれた場合、おそらく2コアの消費者向けCPUでギガバイト/秒で実行できます. この方法でビジネス ロジック全体にアプローチしたと聞いた中で最も有名な例は、LMAX 外国為替取引所です。

すべての理論を忘れて、< 1 GB/s に満足している場合、私が見つけた Windows での 1 つの可能な出発点は、sdk/driver サンプルを掘り下げたくない場合を除いて、winimage からの readfile ソースを見ることです。SSD の速度でパフォーマンスを正しく計算するには、ソース コードの修正が必要になる場合があります。バッファサイズも試してみてください。スイッチ/hマルチスレッドおよび/oオーバーラップ(完了ポート)IOは、最適なバッファサイズ(32、64、128 KBなどを試してください)で、私の経験ではWindowsファイルバッファリングを使用せず、同時に処理しながらSSD(コールドデータ)から読み取るときに最高のパフォーマンスを発揮します(Adler 処理には /a を使用します。そうしないと、CPU バウンドになりすぎます)。

于 2013-12-16T07:59:23.487 に答える
0

シーケンスが本当に重要であるかどうかは、問題には記載されていません。したがって、ファイルをそれぞれ 1GB の等分に分割します。複数の CPU を使用しているため、複数のスレッドが問題になることはありません。したがって、個別のスレッドを使用して各ファイルを読み取り、容量が 10 GB を超える RAM を使用すると、すべてのコンテンツが複数のスレッドによって読み取られる RAM に格納されます。

于 2009-10-12T18:04:30.680 に答える
0

私たちが大きなファイルを読んでいたプロジェクトを思い出したようです.私たちの実装はマルチスレッドを使用していました.より小さな情報のチャンクを読み取る。他の誰かが全体を設計していたので、これについての私たちの推論を正確に思い出すことはできません.労働者だけがそれをしたわけではありませんが、それは大まかに私たちがそれをした方法です.

それが役に立てば幸い

于 2009-08-28T22:17:33.890 に答える