2

私のJavaアプリケーションは基本的にこれを行います:

  • ファイルから nThread バッファを読み取ります (1 mb バイトの arryas)
  • バッファを処理する nThread スレッドを作成する
  • スレッドがデータを処理するのを待つ
  • 処理済みデータを別のファイルに書き込む

これは、コアごとに理論上 100% の速度向上を達成する必要があるアプリケーションの 1 つですが、代わりに、情報を処理するスレッドが増えるほど、速度が遅くなります!

例:

  • 1 スレッド: 4800 ミリ秒
  • 2 スレッド: 10200 ミリ秒
  • 3 スレッド: 13400 ミリ秒
  • 4 スレッド: 18560 ミリ秒
  • 等々
4

2 に答える 2

1

スレッドを追加するときにそのようなパフォーマンスが得られるということは、本当に間違ったことをしていることを意味します。多くの場合、スレッドを追加しても速度は向上せず、多少不利になることもありますが、別のスレッドを追加してプログラムの実行時間が 2 倍になることは非常にまれです。

調査すべき事項は次のとおりです。

  • @Tudor がコメントで述べたように、単一のスレッドから入力ファイルを読み取り、作業をワーカー スレッドにディスパッチする必要があります。
  • ExecutorService独自のスレッドを自分で管理する代わりに、を使用することを検討する必要があります。これにより、通常、多くのユーザー コードと関連するバグが削除されます。を参照してくださいExecutors.newFixedThreadPool(numThread)
  • スレッドを正しく開始していますか? new Thread(...).start()直接電話するのではなく、電話する必要がありますrun()
  • 次のスレッドを開始するjoin() 前に電話していますか? start()すべてのスレッドに行をディスパッチし、最後にそれらにディスパッチする必要がありますjoin()
  • すべての入力行を誤ってすべてのスレッドに送信している可能性はありますか? ただし、出力IOも増加させない限り、これがパフォーマンスの数値を示すとは思いません。

質問でスレッド コードの一部を示していただければ、さらにお役に立てます。

于 2012-05-14T16:18:37.757 に答える
0

適切に最適化されていないコードは、通常、それだけでメモリ帯域幅全体を使い果たします。マルチコア プロセッサで同じ最適化されていないコードを使用する別のスレッドを追加すると、スレッド間で帯域幅が分割され、さらに、かなり頻繁に相互に実行され、処理がさらに遅くなります。

グレイ氏は、「... プログラムの実行時間を 2 倍にすることは非常に珍しいことです」と述べています。同意しません。これは通常、メモリ アクセスの最適化を開始する前に C コードで発生することです。最初から減速が見られないのは非常に珍しいことだと思います。

Java でサンプリングが利用できるかどうかはわかりませんが、そこから始めるのは明らかです。

于 2012-05-14T19:09:45.070 に答える