回答:
これは複雑な質問です。スレッドの性質について詳しく知らなければ、言うのは困難です。システムパフォーマンスを診断する際に考慮すべき事項:
プロセス/スレッドです
これら3つのリソースはすべて有限であり、いずれもシステムのパフォーマンスを制限できます。特定の状況がどれを消費しているのかを確認する必要があります(2つまたは3つ)。
およびを使用ntop
してiostat
、vmstat
何が起こっているかを診断できます。
「なぜこれが起こるのですか?」答えは簡単です。4人を横に並べることができる廊下があるとします。片方の端にあるすべてのゴミをもう片方に移動します。最も効率的な人数は4人です。
1〜3人の人がいる場合、廊下スペースの使用を逃しています。5人以上の人がいる場合、それらの人の少なくとも1人は基本的に他の人の後ろで常にキューに入れられています。より多くの人を追加すると、廊下が詰まるだけで、活動性は加速しません。
したがって、待ち行列を発生させることなく、できるだけ多くの人を収容したいと考えています。 キューイング(またはボトルネック)がある理由は、slmの回答の質問に依存します。
4
が最適な数字です。
一般的な推奨事項は、n + 1スレッドです。nは使用可能なCPUコアの数です。これにより、1つのスレッドがディスクI / Oを待機している間に、n個のスレッドがCPUを処理できます。スレッドが少ないとCPUリソースを完全に利用できず(ある時点では常にI / Oが待機します)、スレッドが多いとスレッドがCPUリソースを争います。
スレッドは無料ではありませんが、コンテキストスイッチのようなオーバーヘッドが発生します。通常、スレッド間でデータを交換する必要がある場合は、さまざまなロックメカニズムがあります。これは、コードを実行する専用のCPUコアが実際にある場合にのみ、コストの価値があります。シングルコアCPUでは、通常、単一のプロセス(個別のスレッドはありません)は、どのスレッド処理よりも高速です。スレッドは魔法のようにCPUを速くするわけではなく、単に余分な作業を意味します。
他の人が指摘しているように(slm answer、EightBitTony answer)、これは複雑な質問であり、あなたが何をしたか、どのようにそれを行うかを説明していないためです。
しかし、より多くのスレッドを確実にスローすると、事態が悪化する可能性があります。
並列コンピューティングの分野には、適用できる(またはできない、しかし、あなたの問題の詳細を記述しないなど)アムダールの法則があり、このクラスの問題に関する一般的な洞察を与えることができます。
アムダールの法則の要点は、どのプログラム(どのアルゴリズムでも)には常に並行して実行できない割合(順次部分)と、並行して実行できる別の割合(並行部分)があることです[明らかにこれらの2つの部分の合計は100%です。
この部分は、実行時間の割合として表すことができます。たとえば、厳密にシーケンシャルな操作に費やす時間の25%があり、残りの75%の時間は、並行して実行できる操作に費やすことができます。
(ウィキペディアの画像)
アムダールの法則は、プログラムの並列部分(75%など)ごとに、より多くのプロセッサを使用して作業を行う場合でも、これまで(たとえば最大4倍)だけ実行を高速化できると予測しています。
経験則として、並列実行で変換できないプログラムが多くなればなるほど、より多くの実行ユニット(プロセッサ)を使用して得ることができなくなります。
物理プロセッサではなくスレッドを使用している場合、状況はこれよりさらに悪化する可能性があります。スレッドは、同じ物理プロセッサ/コア(別の回答で指摘されているように、マルチタスクの形式です)を共有する(CPUとコアなどの使用可能なハードウェアに応じて)処理できることに注意してください。
この理論的な予測(約CPU時間)では、他の実用的なボトルネックは次のように考慮されません。
実際のアプリケーションでは、これが簡単に制限要因になります。
ここでの犯人は「コンテキスト切り替え」であるはずです。現在のスレッドの状態を保存して、別のスレッドの実行を開始するプロセスです。複数のスレッドに同じ優先順位が与えられている場合、実行が完了するまでそれらを切り替える必要があります。
あなたの場合、50個のスレッドがある場合、10個のスレッドを実行するだけと比較すると、多くのコンテキストの切り替えが発生します。
コンテキストの切り替えのために導入されたこの時間のオーバーヘッドは、プログラムの実行を遅くするものです
ps ax | wc -l
225プロセスを報告し、決して負荷が高いわけではありません)。私は@EightBitTonyの推測にしたがいます。キャッシュの無効化は、キャッシュをフラッシュするたびに、CPUがRAMからのコードとデータを何年も待つ必要があるため、大きな問題になる可能性があります。
EightBitTonyのメタファーを修正するには:
「なぜこれが起こるのですか?」簡単に答えられます。あなたが持っている想像して2つのスイミングプール、完全な1と1つの空を。すべての水を一方から他方に移動し、4つのバケツを持ちます。最も効率的な人数は4です。
1〜3人の人がいるならば、いくつかのバケツを使うのを逃しています。5人以上の人がいる場合、そのうちの少なくとも1人がバケツを待って立ち往生しています。より多くの人を追加しても、アクティビティはスピードアップしません。
そのため、同時にいくつかの作業(バケットを使用)を実行できる数の人が必要です。
ここでの人はスレッドであり、バケットはボトルネックとなっている実行リソースを表します。スレッドを追加しても、何もできない場合は役に立ちません。さらに、バケツをある人から別の人に渡すのは通常、同じ人がバケツを同じ距離だけ運ぶよりも遅いことを強調する必要があります。つまり、コアで交互に実行される2つのスレッドは、通常、2倍の長さで実行される1つのスレッドよりも少ない作業を実行します。これは、2つのスレッドを切り替える余分な作業が原因です。
制限実行リソース(バケット)がCPU、コア、または目的のハイパースレッド命令パイプラインであるかどうかは、アーキテクチャのどの部分が制限要因であるかによって異なります。また、スレッドは完全に独立していると仮定しています。これは、データを共有しない(およびキャッシュの衝突を回避する)場合のみです。
数人の人が示唆しているように、I / Oの場合、制限リソースは、キューイング可能なI / O操作の数になります。これは、ハードウェアとカーネルの要因全体に依存しますが、コア。ここでは、実行バインドコードと比較して非常に高価なコンテキストスイッチは、I / Oバインドコードと比較してかなり安価です。残念ながら、これをバケットで正当化しようとすると、隠metaは完全に制御不能になると思います。
ことを注意最適な I / Oバウンドコードで動作が一般的である、まだパイプライン/コア/ CPUあたり最大1つのスレッドで持っています。ただし、非同期または同期/非ブロッキングI / Oコードを作成する必要があり、比較的小さなパフォーマンスの改善が常に余分な複雑さを正当化するとは限りません。
PS。元の廊下のメタファーに関する私の問題は、4つの人の列があり、2つの列がゴミを運び、2つの列がより多くを集めるために戻ることができることを強く示唆していることです。そして、あなたは廊下とほぼ限り、各キューを作ることができ、そして追加の人がやったアルゴリズムのスピードアップを(あなたは、基本的には、コンベヤベルトに全体の廊下を回しました)。
実際、このシナリオは、TCPネットワーキングでの待ち時間とウィンドウサイズの関係に関する標準的な説明と非常によく似ているため、私は飛び出しました。