31

シナリオ:サンプルアプリケーションがあり、3つの異なるシステム構成があります-

- 2 core processor, 2 GB RAM, 60 GB HHD,
- 4 core processor, 4 GB RAM, 80 GB HHD,
- 8 core processor, 8 GB RAM, 120 GB HHD

アプリケーションのH/W機能を効果的に活用するために、noを構成したいと思います。アプリケーションレベルでのスレッドの数。ただし、これは、システムの機能を完全に理解した後でのみ実行したいと思います。

最大数と最小数を参照してシステムの能力を判断する方法(システム/モード/ツール)はありますか?スレッドの数は、効率とパフォーマンスを損なうことなく、最適にサービスを提供できます。これにより、完全な正義を実行し、それぞれのハードウェア構成で最高のパフォーマンスを実現するアプリケーションの値のみを構成できました。

Edited1:特定 のハードウェア構成のベースラインを設定する方法についての情報を教えてください。

Edited2: より直接的にするために-一般的/全体的なレベルでのスレッドのCPU管理についてある程度理解するために読むことができるリソース/書き込みについて学び/知りたい。

4

8 に答える 8

69

使用するスレッドの最適な数は、いくつかの要因によって異なりますが、ほとんどの場合、使用可能なプロセッサの数と、タスクが CPU をどの程度使用するかによって決まります。Java Concurrency in Practice では、最適なスレッド数を見積もるために次の公式を提案しています。

N_threads = N_cpu * U_cpu * (1 + W / C)

どこ:

  • N_threads は最適なスレッド数です
  • N_cpu はプロセッサの数で、次から取得できます。Runtime.getRuntime().availableProcessors();
  • U_cpu は、ターゲットの CPU 使用率です (使用可能なリソースをすべて使用する場合は 1)。
  • W / C は、計算時間に対する待機時間の比率です (CPU バウンド タスクの場合は 0、遅い I/O タスクの場合は 10 または 100 になります)。

したがって、たとえば、CPU バウンドのシナリオでは、CPU と同じ数のスレッドを持つことになります (その数 + 1 を使用することを支持する人もいますが、それによって大きな違いが生じることは見たことがありません)。

Web クローラーなどの遅い I/O プロセスの場合、ページのダウンロードが処理よりも 10 倍遅い場合、W/C は 10 になる可能性があります。この場合、100 スレッドを使用すると便利です。

ただし、実際には上限があることに注意してください (10,000 スレッドを使用しても通常は高速化されず、通常のメモリ設定ですべてを開始する前に OutOfMemoryError が発生する可能性があります)。

これは、アプリケーションが実行される環境について何も知らない場合に得られる最良の見積もりです。本番環境でアプリケーションをプロファイリングすると、設定を微調整できる場合があります。

厳密には関係ありませんが、プログラムの並列化によって期待できる最大の速度向上を測定することを目的としたアムダールの法則にも興味があるかもしれません。

于 2012-12-19T18:37:23.820 に答える
15

私の推奨事項は、マシンごとのスレッド数を割り当てるための構成およびコマンドライン スイッチを提供することです。ユーザー/管理者がアプリケーションを別の方法で明示的に構成していない場合は、こちらの他の回答で示されているように、Runtime.getRuntime().availableProcessors() に基づくヒューリスティックを使用します。いくつかの理由から、排他的なヒューリスティックベースのスレッドからコアへの推測を強くお勧めします。

  • 最新のハードウェアのほとんどは、ますますあいまいなタイプの「ハードウェア スレッド」に向かっています。Intel のハイパースレッディングや AMD の計算モジュールなどの SMT モデルは式を複雑にし (詳細は以下を参照)、実行時にこの情報を照会することは困難な場合があります。

  • 最新のハードウェアのほとんどには、アクティブなコアと周囲温度に基づいて速度をスケーリングするターボ機能があります。ターボ技術が向上するにつれて、速度 (ghz) の範囲が広がります。一部の最近の Intel および AMD チップは 2.6ghz (すべてのコアがアクティブ) から 3.6ghz (シングル/デュアル コアがアクティブ) の範囲であり、SMT と組み合わせると、前の設計で各スレッドが効果的な 1.6ghz ~ 2.0ghz のスループットを得ることができます。現在、実行時にこの情報を照会する方法はありません。

  • アプリケーションがターゲット システム上で実行される唯一のプロセスであるという強い保証がない場合、やみくもにすべての CPU リソースを消費することは、ユーザーまたはサーバー管理者を喜ばせない可能性があります (ソフトウェアがユーザー アプリかサーバー アプリかによって異なります)。 .

オペレーティング システム全体を自前のマルチタスク カーネルに置き換えることなく、実行時にマシンの残りの部分で何が起こっているかを知る確実な方法はありません。ソフトウェアは、プロセスにクエリを実行したり、CPU 負荷を調べたりすることで、知識に基づいた推測を試みることができますが、それを行うのは複雑であり、有用性は特定の種類のアプリケーション (あなたのアプリケーションが該当する可能性があります) に限定され、通常は昇格または特権の恩恵を受けるか、または必要とします。アクセス レベル。

  • 最新のウイルス スキャナーは、最新のオペレーティング システムによって提供される特別な優先度フラグを設定することで機能します。「システムがアイドル状態」のときにOSに通知させます。OS は、CPU 負荷だけでなく、ユーザー入力や、ムービー プレーヤーなどによって設定された可能性のあるマルチメディア フラグも考慮して決定を下します。これは、ほとんどアイドル状態のタスクでは問題ありませんが、あなたの。

  • 分散型ホーム コンピューティング アプリ (BOINC、Folding@Home など) は、実行中のプロセスとシステムの CPU 負荷を定期的に (1 秒または 0.5 秒ごとに) 照会することによって機能します。アプリに属さないプロセスで負荷が連続して複数のクエリで検出された場合、アプリは計算を中断します。いくつかのクエリで負荷が低くなると、再開します。CPU 負荷の読み取り値は短時間のスパイクで悪名高いため、複数のクエリが必要です。まだ注意事項があります: 1. ユーザーは、BOINC を自分のマシンの仕様に合わせて手動で再構成することをお勧めします。2. 管理者権限なしで BOINC を実行すると、他のユーザーによって開始されたプロセス (一部のサービス プロセスを含む) が認識されないため、CPU リソースをめぐって不当に競合する可能性があります。

SMT (ハイパースレッディング、計算モジュール) について:

最近では、ほとんどの SMT がハードウェア コアまたはスレッドとしてレポートされますが、SMT システムのすべてのコアにわたってスケーリングされたときに最適に実行されるアプリケーションはほとんどないため、通常は適切ではありません。さらに悪いことに、コアが共有 (SMT) であるか専用であるかを照会しても、多くの場合、期待される結果が得られません。場合によっては、OS 自体が単に認識していないことがあります (たとえば、Windows 7 は AMD Bulldozer の共有コア設計を認識していません)。信頼できる SMT カウントを取得できる場合、経験則として、各 SMT を CPU 集中型タスクの半分のスレッドとしてカウントし、ほとんどアイドル状態のタスクの完全なスレッドとしてカウントします。しかし実際には、SMT の重みは、SMT が実行する計算の種類とターゲット アーキテクチャによって異なります。Intel と AMD の SMT 実装は、互いにほぼ反対の動作をします。たとえば、Intel の s は、整数演算と分岐演算がロードされたタスクの並列実行に優れています。AMD は、SIMD とメモリ操作を並行して実行することに長けています。

ターボ機能について:

最近のほとんどの CPU には非常に効果的な組み込みの Turbo サポートがあり、システムのすべてのコアにわたるスケーリングから得られる価値がさらに低下します。さらに悪いことに、ターボ機能は、CPU 負荷と同じくらいシステムの実際の温度に基づいている場合があるため、タワー自体の冷却システムは、CPU の仕様と同じくらい速度に影響します。たとえば、特定の AMD A10 (ブルドーザー) では、2 つのスレッドで 3.7 GHz で実行されていることがわかりました。3 番目のスレッドが開始されると 3.5 GHz に低下し、4 番目のスレッドが開始されると 3.4 GHz に低下しました。これも統合された GPU であるため、4 つのスレッドと GPU が動作している場合、約 3.0 GHz まで低下しました (高負荷のシナリオでは、A10 CPU は内部的に GPU を優先します)。ただし、2 つのスレッドと GPU がアクティブな状態で 3.6 GHz を使用することはできます。私のアプリケーションは CPU と GPU の両方を使用していたので、これは重要な発見でした。プロセスを 2 つの CPU バウンド スレッドに制限することで、全体的なパフォーマンスを向上させることができました (他の 2 つの共有コアは引き続き役に立ちました。それらは GPU サービス スレッドとして機能し、新しいデータを GPU にプッシュするためにすばやく応答して起動できます。必要に応じて)。

...しかし同時に、4x スレッドでの私のアプリケーションは、高品質の冷却デバイスがインストールされたシステムではるかに優れたパフォーマンスを発揮した可能性があります。それはすべて非常に複雑です。

結論: 良い答えはありません。CPU SMT/Turbo 設計の分野は進化し続けているため、良い答えがすぐに見つかるとは思えません。今日定式化した適切なヒューリスティックは、明日には理想的な結果をもたらさない可能性があります。したがって、私の推奨事項は次のとおりです。時間を無駄にしないでください。ローカルの目的に十分に適したコア数に基づいて大まかに推測し、構成/スイッチによってオーバーライドできるようにして、先に進みます。

于 2012-12-24T18:29:14.070 に答える
14

次のように、JVM で使用可能なプロセッサの数を取得できます。

Runtime.getRuntime().availableProcessors()

ただし、残念ながら、使用可能なプロセッサの数から最適なスレッド数を計算することは簡単ではありません。これは、アプリケーションの特性に大きく依存します。たとえば、プロセッサの数よりも多くのスレッドを持つ CPU バウンドのアプリケーションではほとんど意味がありませんが、アプリケーションの大部分が IO バウンドの場合は、より多くのスレッドを使用する必要があります。また、リソースを集中的に使用する他のプロセスがシステムで実行されているかどうかも考慮する必要があります。

ハードウェア構成ごとに経験的に最適なスレッド数を決定し、これらの数をアプリケーションで使用するのが最善の戦略だと思います。

于 2012-12-12T07:56:30.997 に答える
4

私は、最良のアプローチを推奨し、デフォルトをオーバーライドするための構成を提供する他の回答に同意します。

さらに、アプリケーションが特にCPUを集中的に使用する場合は、アプリケーションを特定のプロセッサに「固定」することを検討することをお勧めします。

プライマリオペレーティングシステムが何であるか、または複数のオペレーティングシステムをサポートしているかどうかはわかりませんが、ほとんどの場合、これを行う方法があります。たとえば、Linuxにはタスクセットがあります。

一般的なアプローチは、CPU 0(常にOSによって使用される)を回避し、アプリケーションのCPUアフィニティを同じソケットにあるCPUのグループに設定することです。

アプリのスレッドをCPU0から遠ざける(可能であれば他のアプリケーションから遠ざける)と、タスク切り替えの量が減り、パフォーマンスが向上することがよくあります。

アプリケーションを1つのソケットに保持すると、アプリのスレッドがCPU間で切り替わるときにキャッシュの無効化が減少するため、パフォーマンスがさらに向上します。

他のすべての場合と同様に、これは、実行しているマシンのアーキテクチャ、および実行している他のアプリケーションに大きく依存します。

于 2012-12-25T01:26:00.320 に答える
2

VisualVmツールを使用してスレッドを監視します。最初にプログラムで最小限のスレッドを作成し、そのパフォーマンスを確認します。次に、プログラム内のスレッドの数を増やして、パフォーマンスを再度分析します。

于 2012-12-21T13:00:40.773 に答える
1

ここでは、この Python スクリプトを使用して、最適なパラメーターとエルゴノミクスで Java アプリケーションを起動するためのコア (およびメモリなど) の数を決定します。Github の PlatformWise

これは次のように動作します:getNumberOfCPUCores()上記のスクリプトで を呼び出してコア数とgetSystemMemoryInMB()RAM を取得する python スクリプトを作成します。コマンドライン引数を介してその通知をプログラムに渡すことができます。その後、プログラムは、コア数に基づいて適切な数のスレッドを使用できます。

于 2012-12-25T06:39:43.443 に答える
1

アプリケーション レベルでスレッドを作成するのは良いことです。マルチコア プロセッサでは、コア上で個別のスレッドを実行してパフォーマンスを向上させます。そのため、コアの処理能力を利用するには、スレッド化を実装するのがベスト プラクティスです。

私が思うこと:

  1. 一度に 1 つのコアで実行されるプログラムのスレッドは 1 つだけです。
  2. 2 スレッドの同じアプリケーションは、2 コアで半分の時間で実行されます。
  3. 4 スレッドの同じアプリケーションは、4 コアでより高速に実行されます。

したがって、開発するアプリケーションには、スレッド レベル <= コア数が必要です。

スレッドの実行時間はオペレーティング システムによって管理され、非常に予測不可能なアクティビティです。CPU 実行時間は、タイム スライスまたはクォンタムと呼ばれます。より多くのスレッドを作成すると、オペレーティング システムはこのタイム スライスの一部を最初に実行するスレッドの決定に費やすため、各スレッドの実際の実行時間が短縮されます。言い換えれば、多数のスレッドがキューに入れられている場合、各スレッドが行う作業は少なくなります。

これを読んで、CPU コアの実際の使用方法を理解してください。素晴らしいコンテンツです。 csharp-codesamples.com/2009/03/threading-on-multi-core-cpus/

于 2012-12-26T09:17:27.990 に答える