2

巨大な(数ギガバイトの)ASCIIテキストファイルがあり、行ごとに読み取り、特定の列を浮動小数点に変換し、これらの数値に対していくつかの簡単な操作を行う必要があります。それはかなり簡単なことですが、それを全体的にスピードアップする方法がなければならないと私は考えています。このプログラムは、I / Oの待機に非常に多くの時間を費やすため、CPUコアの100%に相当するものを使用することはありません。同時に、I / Oの代わりに計算を行うのに十分な時間を費やしているため、rawディスクI / Oは約8〜10MB/秒しか実行されません。私のハードドライブはそれよりもはるかに優れているのを見てきました。

I / Oと処理を別々のスレッドで行うと役立つでしょうか?もしそうなら、これを実装する効率的な方法は何ですか?重要な問題は、私がボトルネックにならないように、各行を保持するためのメモリ割り当てをどうするかです。

編集:私は現在、Dプログラミング言語、バージョン2の標準ライブラリ、主に高レベルの関数を使用しています。std.stdio.Fileで使用されるバッファサイズは16KBです。

4

4 に答える 4

1

100% の CPU を使用していない場合は、I/O バウンドであり、マルチスレッドによる改善はほとんど見られません。I/O を待機しているスレッドがいくつかあるだけです。実際、ファイルの別の部分にアクセスしている場合は、ディスク シークを導入して事態をさらに悪化させる可能性があります。

I/O に使用できるバッファ RAM の量を増やすことはできますか? (たとえば C++ では、FILE オブジェクトの標準 I/O バッファは小さい (たとえば 4kB) ため、より大きなバッファ (たとえば 64kB) を設定すると、スループットに大きな違いが生じる可能性があります)。

I/O 要求でより大きなバッファ サイズを使用できますか。たとえば、一度に 1 行または 1 バイトを読み取るのではなく、64KB の生データを大きなバッファに読み取ってから、それを自分で処理します。

データを出力していますか?これをすぐにディスクに書き戻すのではなく、RAM にキャッシュすることで、IO を入力ファイルの純粋な読み取りに制限することができ、処理が大幅に高速化されます。

データの大きなバッファをロードすると、CPU バウンドになり始めることに気付くかもしれません。その時点で、マルチスレッドについて考えることができます。つまり、1 つのスレッドがデータを読み取り、別のスレッドがそれを処理します。

于 2010-01-14T19:30:49.003 に答える
0

十分な RAM がある場合は、ファイル全体を文字列に読み取り、行区切り記号でトークン化し、必要に応じてトークンを処理できます。

Java では、StringBuilder オブジェクトを使用してファイルの内容を読み込みます。次のようなものを使用して、十分なメモリ制限 (この例では 2GB) で jvm を起動することもできます。

java -Xmx 2048 -Xms 2048 -jar MyMemoryHungryApp.jar

ファイル全体を文字列に読み取りたくない場合は、バッチで繰り返し読み取り、バッチを処理できます。

実際、ファイル形式の詳細によっては、オープン ソースの Java パッケージ (プロジェクト ページ) である CSVReader を使用して、readAll() メソッドでファイルをメモリに読み込むList<String[]>ことができます。その上で町に行きます:)。

于 2010-01-14T19:30:19.517 に答える
0

まず第一に、私はあなたが持っているプログラムを取り、それのスタックショットを取得します. これにより、I/O に費やされた時間と CPU に費やされた時間が確実にわかります。

次に、I/O が支配的な場合は、ディスク ヘッドの動きを最小限に抑えるために、できるだけ大きなバッファーを読み取るようにします。

次に、I/O が CPU で待機しており、続いて CPU が I/O で待機している場合は、非同期 I/O を実行して、CPU が別のバッファーで実行されている間に一方のバッファーをロードできるようにします。(または、リーダー スレッドを使用して代替バッファーに読み込むこともできます。)

I/O が支配的ではなく、CPU が支配的である場合、CPU アクティビティについてどのスタックショットが教えてくれるかがわかります。浮動小数点数のフォーマット解除に非常に多くの時間が費やされている場合、および数値がかなり単純なフォーマットである場合は、単純なフォーマットを利用できるため、自分で解析することを検討します。

それは役に立ちますか?

于 2010-01-14T19:31:09.567 に答える
0

通常、OS は先読みを試みます。CPU バウンドでなければ、ハード ディスクの限界速度に近づくはずです。

次の原因が考えられます。

  • 大きなファイルが断片化されています (ボリュームを最適化して、問題が改善するかどうかを確認してください)
  • OS は先読みを使用しません (解決策として: Windows では、ファイルをスキャンするフラグを付けて CreateFile を使用できます)。
  • 効率的なバッファリングを使用していない (たとえば、OS ファイル ハンドルから一度に数バイトしか読み取らない場合、処理が遅くなります。(一度に大きなチャンクを読み取ろうとする場合があります)。

CPU バウンドになった瞬間に、データのより効率的な解析を検討し始める必要があります。

于 2010-01-14T19:33:04.520 に答える