Spring Batchの並列ステップのように、並列モードをサポートするバッチフレームワークで実行されるバッチプログラムで理想的な数のスレッドを取得する必要があります。
私の知る限り、プログラムのステップを実行するにはスレッドが多すぎるのは良くありません。プログラムのパフォーマンスに悪影響を与える可能性があります。いくつかの要因がパフォーマンスの低下を引き起こす可能性があります(コンテキストの切り替え、共有リソースを使用する場合の競合状態(ロック、同期..)...(他の要因はありますか?))。
もちろん、理想的なスレッド数を取得する最良の方法は、プログラムのスレッド数を調整する実際のプログラムテストを行うことです。しかし、私の状況では、テストには多くのもの(人、テストのスケジュール、テストデータなど)が必要であり、今は準備が難しいため、実際のテストを行うのはそれほど簡単ではありません。したがって、実際のテストを取得する前に、プログラムのスレッドの理想的な数をできるだけ多く取得する方法を知りたいと思います。プログラムの理想的なスレッド(ステップ)数を取得するには、何を考慮する必要がありますか? CPUコアの数??私のプログラムが実行されるマシン上のプロセスの数??データベース接続の数??このような状況で式のような合理的な方法はありますか?
最も重要な考慮事項は、アプリケーション/計算がCPUバウンドであるかIOバウンドであるかです。
一般的な方程式:
スレッド数<=(コア数)/(1-ブロッキング係数)
ここで、0 <=ブロッキング係数<1
マシンのコア数:Runtime.getRuntime().availableProcessors()
並列処理できるスレッドの数。次のコードを出力することで取得できます。
ForkJoinPool.commonPool()
そして、数の並列処理は、マシンのコア数-1です。これはメインスレッド用だからです。
時間:1:09:00
プログラムの理想的なスレッド(ステップ)数を取得するには、何を考慮する必要がありますか? CPUコアの数??私のプログラムが実行されるマシン上のプロセスの数??データベース接続の数??このような状況で式のような合理的な方法はありますか?
これは、スレッド化する実際のコードに関する多くの知識がなければ、実行するのが非常に困難です。 @Erwinが言及しているように、IO対CPUバウンド操作は、アプリケーションのスレッド化によって改善が見られるかどうかを判断する前に必要な重要な知識です。特定のハードウェアのスイートスポットを見つけたら、別のサーバー(または仮想クラウドノードの別のインスタンス)で起動して、根本的に異なるパフォーマンスの数値を確認できます。
考慮すべきことの1つは、実行時にスレッドの数を変更することです。 ThreadPoolExecutor.setCorePoolSize(...)
は、スレッドプールの動作後に呼び出されるように設計されています。これを手動で行うために、いくつかのJMXフックを公開できます。
また、アプリケーションが実行時にアプリケーションまたはシステムのCPU使用率を監視し、そのフィードバックに基づいて値を微調整できるようにすることもできます。また、AtomicLong
スループットカウンターを維持し、実行時にスレッドを上下にダイヤルして、スループットを最大化することもできます。ただし、それを正しく行うのは難しいかもしれません。
私は通常、次のことを試みます。