並列 Java プログラムを作成しました。通常は次のように機能します。
- 入力
String input
として を受け取ります。 - 次に、均等に
input
カットされます。String inputs[numThreads]
- それぞれ
inputs[i]
が処理に割り当てられthread_i
、生成されresults[i]
ます。 - すべての作業スレッドが終了すると、
main
スレッドは を にマージresults[i]
しresult
ます。
10 コア (物理コア) マシンでのパフォーマンス データは次のとおりです。
Threads# 1 thread 2 threads 4 threads 8 threads 10 threads
Time(ms) 78 41 28 21 21
ノート:
- JVM のウォームアップ時間がなくなりました (最初の 50 回の実行)。
- 時間には、スレッドの開始/参加時間は含まれません。
スレッド数が 8 を超えると、メモリ帯域幅がボトルネックになるようです。
この場合、パフォーマンスをさらに向上させるにはどうすればよいでしょうか。並列 Java プログラムに設計上の問題はありますか?
このスケーラビリティの問題の原因を調べるために、(無意味な計算) ループをprocess(inputs[i])
メソッドに挿入しました。新しいデータは次のとおりです。
Threads# 1 thread 10 threads
Time(ms) 41000 4330
新しいデータは、10 スレッドの優れたスケーラビリティを示しています。これは、元の (無意味なループのない) にはメモリの問題があることを示しているため、そのスケーラビリティは 8 スレッドに制限されています。
しかし、とにかくこの問題を回避するには、データを各コアのローカル キャッシュに事前にロードするか、バッチでロードしますか?