3

この質問にはすでに答えがあります。

私はスレッドを扱い始めたばかりですが、すぐにスレッドの数が多すぎるという非常によくある質問に遭遇しました。

いくつかの調査をした後、私はさらに混乱しました。

仕事

私は16個のコアと1000個のオブジェクトを生成するアプリケーションを持っています。 msdnのドキュメントによると、1000スレッドを作成すると、通常、マルチスレッドによるパフォーマンス上の利点が損なわれ、大きなオーバーヘッドが発生します。最大スレッド数。また、私は3.5 NET 32ビットの制限内に留まらなければなりません(.NETアプリの最大スレッド数は?

質問1

このような一方的な仕事をすることは、コンピュータ上のコアよりも多くのスレッドを作成することが可能ですか? .NETはそこで何かを最適化していますか?使用するスレッドの最大数はいくつですか?

質問2

単純な美しい解決策はありますか。それ以外に、制限のあるリソースでそれをキューに入れるという方法はありますか。 1000個すべてのスレッドを作成しても、デフォルトのスレッドスタックを割り当てないようにすぐにスレッドを非アクティブにするセマフォのようなものはありますか。


  • スレッドプールは役に立つ概念です。 - Chris O
  • あなたはそれほど多くのスレッドを作成してはいけません、コアの数と同じくらい多くのスレッドを作成して、そして1つ以上のタスクを完了するためにスレッドを再利用するべきです。 - Marko
  • あなたの質問に欠けているのはあなたがスレッドがすると思うことです。 1000個のオブジェクトを作成するのに1000個のスレッドが必要だと思うのはなぜですか? - CodeCaster
  • 最初の質問は、既存の良い重複があります。 2番目の質問(実際には同じ投稿で質問されるべきではありません...)は現時点では非常に広く、具体的な答えを得ることはほとんどありません - いずれにしてもマルチスレッドで最適化することを望んでいます。 - Alexei Levenkov

3 답변


5

はい。オペレーティングシステムのスケジューラは、コアよりも多くのスレッドを作成することができます(おそらくそうすべきです)。意志アクティブスレッド間のスワップを中断そのコアで他に何も待っていなくても。ただし、1000個のスレッドを別々に作成したくない場合もあります。代わりに、いくつかのスレッドを作成し、それらの間で作業を分割して、各スレッドがフルジョブからの複数の項目を処理するようにします。

私は、経験則として、論理コアごとに2つのスレッドを使用することをお勧めします(これはハイパースレッドコアを対象とします。16論理コア用のハイパースレッドを備えた8コアCPUの場合、32スレッドを作成します)。考えはできるだけ少ないスケジューラ割り込み/コンテキストスワップが欲しいということですが、同時にあなたの仕事を中心にしてすべてのコアを忙しくしておくようにしてください。与えられたスケジューラ割り込み意志論理コア上で他に何もアクティブになっていなくても、そのコアに2つのアクティブスレッドを持つことは、スケジューラがプログラムからアイドルスレッドを入れることを意味します。そのコアで他のものがアクティブになっていても、実行用に選択されたスレッドになる可能性があります。これより高くなると、必要以上にコンテキストの切り替えが促進され、パフォーマンスが低下する可能性があります。

短いバージョンは、(コンテキストの切り替えがまだ発生するため)コアあたりのセカンドスレッドのコストは低いですが、見返りは潜在的に高くなります(他の何かの代わりにCPUがあなたのアプリで動作している全体のスケジューラブロック)。コアあたりのスレッド数を増やすと、コストが増加し、潜在的な利益が減少し始めます。

しかしそれは私の経験です。それは極めて一般化されていて、出発点以上のものには向いていません。本当に必要ですプロフィール最高のパフォーマンスを得るためにこれを調整する方法を理解するために、アプリケーションがさまざまなスレッド番号でどのように動作するか。

最後に、.NETの世界では、それを言及する価値がありますThreadPoolそして非同期タスク。これはそれらの主題についての完全なチュートリアルに入るための最良の場所ではありませんが、それらを読むことはあなたの時間に十分価値があります。


3

コンピュータ上のコアよりも多くのスレッドを作成することは可能ですか?

はい、これは可能です。

.NETはそこで何かを最適化していますか?   使用するスレッドの最大数はいくつですか?

実際、99.99%のケースでスレッド数を気にする必要はありません。99.99%のケースでは手動でスレッドを作成してはいけないからです。つかいますThreadPool代わりに、.NET 3.5内に留まる必要がある場合。つかいますタスクバージョンが4.0以上の場合

単純な美しい解決策はありますか。それ以外に、制限のあるリソースでそれをキューに入れるという方法はありますか。

事実、違います。物理的に利用可能なリソースを飛び越えることはできません、これがネックです。


1

基本的に、新しいスレッドのパフォーマンスが上がるにつれて、パフォーマンスの割合はますます低くなります。 10スレッドは1スレッドよりも10倍高速ではありません。また、実行していないコアよりも多くのスレッドを実行している場合意味のあることそれから。

経験則では、UIの応答性を妨げないように、パフォーマンス重視のコードにスレッドを使用して、UIスレッドではなくバックグラウンドで実行するようにします。すでにUIブロックではないコードを最適化したい場合は、ターゲットマシン上のコア数を調べて、必要に応じてさらに重いアルゴリズムを支援するためにスレッドをいくつか作成することができます。マルチスレッドコードをデバッグし、保守して書くのははるかに難しいことを覚えておいてください。

したがって、実験と学習のためにのみ使用し、それ以外の場合はアプリケーションに特別な機能を追加する必要がある場合にのみ使用してください。

答え1:はい、コアよりも多くのスレッドを作成することは可能ですが、それはほとんど意味がありません。

答え2:1000個のオブジェクトを作成するために1000個のスレッドを作成しないでください。それはきれいではありません

リンクされた質問


関連する質問

最近の質問