1

時期尚早の最適化がすべての悪の根源であると彼らが言うことを私は知っています...しかしそれはその頃です。

次の操作を実行する、遅いが動作する手順があります。

  1. file.inputからチャンク(シーケンシャル)を読み取ります
  2. チャンクを変換する
  3. 変換されたチャンクをfile.outputに書き込む(追加する)

file.inputとfile.outputは、最終的に同じサイズの球場(10-100 + GB)になります。チャンクは通常約10Kです。変換ステップは、独自のフォーマット間の変換にすぎません。説明のために、リアルタイム圧縮アルゴリズムと同等の計算値であると見なすことができます。

これらの手順は現在、シングルスレッドで実行されています。

私の質問:これをより良いパフォーマンスにするにはどうすればよいですか?

処理されるデータの純粋な量に基づいてこれが「高速」になることは決してないことを私は理解していますが、これを高速化するための比較的単純で標準的な手法がいくつかあると信じなければなりません。

読み取りステップ(1)にバッファリングを追加してみました。つまり、チャンクサイズよりもはるかに大きなブロックを読み取り、バッファーから読み取ります。これは役に立ちました。ただし、変換ステップ(2)と追加(3)で実行できることがあるかどうかについては、少し行き詰まっています。

Resource Monitorによると、CPU使用率は30〜45%の間で変動し、ディスクI/Oの使用率は一定期間持続します。

ネイティブライブラリへの一連のP/invoke相互運用機能を備えたC#を使用しています。

4

5 に答える 5

2

まず、すべてのステップが費やされた時間の大部分を占めることを確認する必要があります。ボトルネックが1つのステップのみであることが判明した場合、ここでは間違った図を見ています。

ディスクI/Oは、CPUが他のタスクに使用できるようになるまでに時間がかかる場合があるため、マルチスレッドソリューションによってパフォーマンスが向上する可能性があります。おそらく、1つのスレッドを使用して、最大10チャンクの処理可能なデータのバッファーを埋め続けることができます。1つは最初のスレッドによってロードされたチャンクを処理し、もう1つは処理が終了したチャンクを書き込むだけです。次に、のペアはAutoResetEvents、前のスレッドが1つ以上のチャンクの処理を終了したことを各スレッドに通知できます。

于 2012-04-17T21:37:08.597 に答える
2

まず、このシナリオにスレッドを追加しないでください。スレッドはパフォーマンスを向上させるために何もしません。(もちろん、アプリケーションにUIインターフェイスがある場合は、スレッドを追加して集中的な作業を実行し、ユーザーが他のタスクを続行できるようにすることができます)

次に、ディスク上のIOを最小化してみてください。できるだけ多くのバイトを読み取り、すべてを書き込みます。第三に、おそらくあなたの最善の策は、変換作業を最適化することです。

于 2012-04-17T21:39:39.740 に答える
1

.NET 4を使用している場合は、MemoryMappedFileMemoryMappedViewAccessorを試すことができます。

于 2012-04-17T21:34:53.757 に答える
1

測定

  • 1(どこにも単純な順次読み取り)、
  • 3(ランダムバイトの単純な順次書き込み)
  • 1 + 3(16K-64k-512k-1Mbの適度なサイズのブロックを読み取ってすぐにコピーします)
  • 2(計算のみ)

あなたの数を見て、重複がかなりの利益をもたらすことができるかどうかを確認するよりも。45%のCPU負荷はそれほど悪くないので、そのままにしておく方がよい場合があります。

取得できる最善の方法はMax(1、2、3)なので、それに応じて最適化を計画します。

于 2012-04-17T21:40:31.433 に答える
1

あなたの主な問題はI/Oになります。2つのファイルを交互に使用すると、状況が少し悪化します。

  • 読み取りと書き込みの両方をバッファリングします。大きなアクションの方が優れており、この場合は少ないアクションの方が優れています。

CPUを多用する部分もあるので、スレッドを使ってみます。待機を最小限に抑えるために、パイプラインを使用します:ReaderThread-> Queue-> ProcescessingThread-> Queue-> WriterThread

于 2012-04-17T21:48:45.773 に答える