コアあたりの最適なスレッド数


280

たとえば、4コアのCPUがあり、最小限の時間でいくつかのプロセスを実行したいとします。プロセスは理想的には並列化が可能なため、無制限の数のスレッドでそのチャンクを実行でき、各スレッドにかかる時間は同じです。

私は4つのコアを持っているので、単一のコアは特定の瞬間に単一のスレッドしか実行できないため、コアよりも多くのスレッドを実行してもスピードアップは期待できません。私はハードウェアについてあまり知らないので、これは推測にすぎません。

コアよりも多くのスレッドで並列化可能なプロセスを実行する利点はありますか?つまり、4スレッドではなく4000スレッドを使用して実行した場合、プロセスはより速く、遅く、またはほぼ同じ時間で終了しますか?

回答:


253

スレッドがI / Oや同期などを行わず、他に何も実行していない場合は、コアあたり1スレッドで最高のパフォーマンスが得られます。しかし、そうではない可能性が高いです。スレッドを追加すると通常は役立ちますが、ある時点でパフォーマンスが低下します。

少し前まで、Monoでかなりまともな負荷の下でASP.NETアプリケーションを実行する2クアッドコアマシンでパフォーマンステストを行っていました。スレッドの最小数と最大数を試してみたところ、最終的に、その特定の構成での特定のアプリケーションの場合、最高のスループットは36スレッドと40スレッドの間にあることがわかりました。これらの境界の外側にあるものはすべて、パフォーマンスが低下しました。学んだ教訓?私があなただったら、アプリケーションに適した数が見つかるまで、さまざまな数のスレッドでテストします。

1つ確かなことは、4kスレッドの方が時間がかかるということです。これは多くのコンテキストスイッチです。


21
ゴンザロの答えは良いと思います。実験と測定をすべきだと付け加えます。あなたのプログラムは彼、私の、または他の誰かのものとは異なり、あなた自身のプログラムの行動の測定のみがあなたの質問に正しく答えます。並列(または並行)プログラムのパフォーマンスは、第一原理のみから適切な結論を導き出すことができる領域ではありません。
高性能マーク

5
+ 1、+回答:スレッド数がコアよりも多いとパフォーマンスが向上するのは驚くべきことですが、スレッド数が多いと、競合するスレッドと比べてタイムシェアが大きくなるのは当然です。私のアプリケーションがパフォーマンスの違いを検出し、最適なスレッド数に自動的に調整できると便利です。
ジュリエット

12
現実のシナリオであなたを驚かせるべきではありません。スレッドは、ディスクアクセス、ネットワークなどのIOリソースの待機をブロックします。また、他のスレッドのような非IOリソースが共有変数の使用を完了するのを待機します。本当に達成したいのは、コアごとに少なくとも1つのスレッドが常に実行できるようなスレッドの最小数です。
パトロス2009年

4
コアあたり1スレッドは最適ではありません。これは、スレッドが一時的にブロックされている場合に別のスレッドを実行できるようにするため、それよりも少し多く、できれば2倍にする必要があります。メモリ上だけでも。SMT / HTを特徴とするシステム(P4、I7、Sun Rockなど)がある場合、これはより重要です
Marco van de Voort

1
したがって、私の答えでは「そうではない可能性が非常に高い」です。適切な数を見つけることは、アプリケーションとそれが実行されるアーキテクチャーによって異なります。
ゴンザロ

129

@ゴンザロの答えに同意します。私はI / Oを行わないプロセスを持っています、そしてここに私が見つけたものがあります:

ここに画像の説明を入力してください

すべてのスレッドは1つの配列で機能しますが、範囲が異なる(2つのスレッドは同じインデックスにアクセスしない)ため、異なる配列で機能した場合は結果が異なる場合があります。

1.86マシンは、SSDを搭載したMacBook Airです。もう1台のMacは、通常のHDDを搭載したiMacです(7200 rpmだと思います)。Windowsマシンにも7200 rpmのHDDがあります。

このテストでは、最適な数はマシンのコアの数と同じでした。


14
グラフの+1。明らかにコアあたり1スレッドが最適ですが、クアッドコアシステムは他のスレッドのようにスレッド数が多くない(とにかく100未満)ようです。
ジムギャリソン

46
グラフは-1!整数値のx座標による滑らかな曲線?1 2 3から10 20 30から50 100への急激なジャンプ?そして、適切な測定のために10のプラス2の倍数であるy座標。これはExcelの仕事ですよね。
Spacedman、

5
@Spacedmanはい、そうです。滑らかな曲線は、見た目がはるかに優れています。:D
Motasim

22
@PascalvKooten、問題はそれがきれいに見えるということではありません、それは一見偽っています。まず、y軸は42から始まり、テストしたマシン間の明らかな違いを誇張しています。第2に、x軸の値の奇妙な推移は、「時間」が「スレッドの数」に比例しないことを示唆しています。これは特に青い線に当てはまります。他の人(私を含む)が抱えている問題は、データを正しく伝えていないことだと思います。
pauluss86 2013

13
@Spacedmanグラフ上の批評は、過去24時間に私が遭遇した中で最もばかげているものです。グラフが役立ちます。たくさん。限目。それはもっとうまくできただろうか?誰も気にしない。離散ではなく滑らかな曲線?それはあなたの問題ですか???? 私は、あなたがそれを見栄えよくするための余分な時間/エネルギーを持っていないので、あなたのすべてがそのようなグラフを彼らの答えに含めないでしょう。それが私のポイントです。
tyrex 2014年

49

この質問はかなり古いことは承知していますが、物事は2009年から進化しています。

ここで2つの考慮事項があります。コアの数と、各コア内で実行できるスレッドの数です。

Intelプロセッサでは、スレッドの数はハイパースレッディングによって定義され、ハイパースレッディングは2(使用可能な場合)です。しかし、ハイパースレッディングは、2つのスレッドを使用していなくても、実行時間を2つ削減します。(つまり、1つのパイプラインが2つのプロセス間で共有されます。これは、より多くのプロセスがある場合に適しています。それ以外の場合はそれほど優れていません。コアが多いほど、明らかに優れています。)

他のプロセッサでは、2、4、または8つのスレッドさえあるかもしれません。したがって、それぞれが8つのスレッドをサポートする8つのコアがある場合、64のプロセスをコンテキストの切り替えなしで並行して実行できます。

「コンテキストスイッチングなし」は、制御できない他のあらゆる種類のコンテキストスイッチングを行う標準オペレーティングシステムで実行している場合は明らかに当てはまりません。しかし、それが主なアイデアです。一部のOSでは、プロセッサを割り当てることができるため、アプリケーションのみがそのプロセッサにアクセス/使用できます。

私自身の経験から、I / Oが多い場合は、複数のスレッドが適しています。メモリを大量に使用する作業(読み取りソース1、読み取りソース2、高速計算、書き込み)がある場合は、スレッドを増やしても効果がありません。繰り返しますが、これは同時に読み書きするデータの量に依存します(つまり、SSE 4.2を使用して256ビットの値を読み取ると、すべてのスレッドがそのステップで停止します...つまり、1つのスレッドの実装がはるかに簡単で、これはプロセスとメモリアーキテクチャに依存しますが、一部の高度なサーバーは個別のコアの個別のメモリ範囲を管理するため、データが適切にファイリングされていると仮定すると、個別のスレッドが高速になります...アーキテクチャでは、4つのプロセスは、4つのスレッドを持つ1つのプロセスよりも高速に実行されます。)


4
おそらく他にもありますが、私が知っているのはIBMのPOWERプロセッサです。彼らは、プロセッサごとに4または8スレッドのシステムを持っていました。これで、より多くのコアを使用できるようになるため、代わりにコアごとに2つのスレッドを提供します...
Alexis Wilke 2013年

これは古いですが、ほとんどのIntel i5、i7にはマルチスレッドCPUがあります。たとえば、i7 CPUは通常4コアですが、8スレッドです。
Edgar.A

4
プロセッサにはスレッドがありません。彼らは物理的および論理的なコアを持っています。ハイパースレッディングでは、1つの物理コアが2つの論理コアとして機能します。スレッドのあるプロセッサは本物だと主張する技術を持っていたので、スレッドのスピンドルが突き出たプロセッサのホワイトボードに絵を描きました。

これを見て持って@TechnikEmpire intel.com/content/www/us/en/processors/core/...を、多分あなたはインテルに連絡し、彼らはあまりにもスレッド描くことができます。
g7k 2015年

24

実際のパフォーマンスは、各スレッドが自発的に生成する量によって異なります。たとえば、スレッドがまったくI / Oを実行せず、システムサービスを使用しない場合(つまり、100%CPUバウンド)、コアあたり1スレッドが最適です。スレッドが待機を必要とする何かを行う場合、スレッドの最適な数を決定するために実験する必要があります。4000スレッドでは、かなりのスケジューリングオーバーヘッドが発生するため、それもおそらく最適ではありません。


21

答えは、プログラムで使用されるアルゴリズムの複雑さによって異なります。私は、2つの任意の数のスレッド「n」と「m」について、処理時間TnとTmの2つの測定を行うことにより、最適なスレッド数を計算する方法を考え出しました。線形アルゴリズムの場合、スレッドの最適数はN = sqrt((m n(Tm *(n-1)– Tn *(m-1)))/(n Tn-m Tm))になります。

さまざまなアルゴリズムの最適数の計算に関する私の記事を読んでください:pavelkazenin.wordpress.com


4
なぜ反対票が投じられるのですか?申し訳ありませんが、これがこの質問に対する最良の答えです。gonzaloは質問の太字部分を扱い、pkazenはタイトルを扱います。どちらの回答も非常に便利ですが、スレッド数を概算する体系的な方法があるため、pkazenの回答が適しています。彼はさらに、lineaアルゴリズムの公式を示しています。
tobiak777

1
私は反対票を投じなかったが、仮にそうしたとしても、最適なスレッド数がアルゴリズムの複雑さにどのように関連しているのかについての実際の説明がないことに基づいて、リンクされた記事全体を読んで保存します。 (記事が複雑なため)長い記事です。それを超えて、記事のいくつかの側面は私には明確ではありません。最も重要なのは、実験結果が理論をどのように確認するかです。
2018年

また、この計算では、CPUコアの数が無限であると想定しています。これは間違いなく貴重な情報ですが、問題はコアの数が少ない実際のマシンに関するものです。
Navneeth

9

ここで別の視点を追加したいと思いました。答えは、質問が弱いスケーリングと強いスケーリングのどちらを想定しているかによって異なります。

ウィキペディアから:

弱いスケーリング:プロセッサーあたりの固定問題サイズでのプロセッサー時間によるソリューション時間の変化。

強力なスケーリング:解決された時間は、問題の合計サイズが固定されているプロセッサーの数によってどのように変わるか

質問が弱いスケーリングを想定している場合は、@ Gonzaloの回答で十分です。ただし、質問が強力なスケーリングを想定している場合は、さらに追加する必要があります。強力なスケーリングでは、固定のワークロードサイズを想定しているため、スレッドの数を増やすと、各スレッドが処理する必要があるデータのサイズが減少します。最近のCPUでは、メモリアクセスはコストが高く、データをキャッシュに保持して局所性を維持するのに適しています。したがって、各スレッドのデータセットが各コアのキャッシュに収まるときに、スレッドの最適な数が見つかる可能性があります(システムのL1 / L2 / L3キャッシュであるかどうかについては詳しく説明しません)。

これは、スレッドの数がコアの数を超えた場合にも当てはまります。たとえば、4コアマシンで実行されるプログラムに8つの任意の単位(AU)の作業があるとします。

ケース1:各スレッドが2AUを完了する必要がある4つのスレッドで実行します。各スレッドの完了には10秒かかります(キャッシュミスが多い)。4コアの場合、合計時間は10秒になります(10秒* 4スレッド/ 4コア)。

ケース2:各スレッドが1AUを完了する必要がある8つのスレッドで実行します。各スレッドは2秒しかかかりません(キャッシュミスの量が減ったため、5秒ではなく)。4コアの場合、合計時間は4秒になります(2秒* 8スレッド/ 4コア)。

私は問題を簡略化し、他の回答(例:コンテキストスイッチ)で言及されているオーバーヘッドを無視しましたが、使用しているデータサイズによっては、使用可能なコア数よりも多くのスレッド数を用意することが有益であるという点がわかると思います再処理。


7

一度に4000スレッドはかなり高いです。

答えはイエスとノーです。各スレッドで大量のブロッキングI / Oを実行している場合、はい、論理コアごとに最大3または4のスレッドを実行することで大幅なスピードアップを示すことができます。

ただし、多くのブロック処理を実行していない場合は、スレッド化によるオーバーヘッドが増えるため、処理が遅くなります。したがって、プロファイラーを使用して、ボトルネックがそれぞれの並列部分のどこにあるかを確認します。重い計算を行っている場合は、CPUごとに複数のスレッドは役に立ちません。大量のメモリ転送を実行している場合も、それは役に立ちません。ディスクアクセスやインターネットアクセスなどのために大量のI / Oを実行している場合は、複数のスレッドを使用すると、ある程度、または少なくともアプリケーションの応答性が向上します。


7

基準。

アプリケーションのスレッド数を増やし始め、1から始めて、100のようなものに移動し、スレッド数ごとに3〜5の試行を実行し、操作速度とスレッド数のグラフを作成します。 。

4スレッドの場合が最適で、その後はランタイムがわずかに上昇しますが、そうでない場合もあります。アプリケーションの帯域幅が制限されている可能性があります。つまり、メモリにロードしているデータセットが巨大である、キャッシュミスが多いなどの理由で、2つのスレッドが最適です。

テストするまでわかりません。


3

マシンのプロセス数を返すhtopまたはpsコマンドを実行すると、マシンで実行できるスレッドの数がわかります。

'ps'コマンドに関するmanページを使用できます。

man ps

すべてのユーザープロセスの数を計算する場合は、次のいずれかのコマンドを使用できます。

  1. ps -aux| wc -l
  2. ps -eLf | wc -l

ユーザープロセスの数の計算:

  1. ps --User root | wc -l

また、「htop」を使用することもできます[参考]

UbuntuまたはDebianへのインストール:

sudo apt-get install htop

RedhatまたはCentOSへのインストール:

yum install htop
dnf install htop      [On Fedora 22+ releases]

ソースコードからhtopをコンパイルしたい場合は、ここで見つけることができます


2

どのスレッドもブロックしない限り、理想はコアあたり1スレッドです。

これが当てはまらない場合の1つは、コア上で実行されている他のスレッドがあることです。


アプリケーションの実行中に、ユーザーのバックグラウンドプロセスをがらくたのように実行するかどうかによって異なります。さらに言えば、各スレッドにリアルタイムの優先順位を設定して、最大のパワーを得ることができます。しかし、ユーザーはマルチタスクが好きです。
Earlz 2009

2
まあ、私たちは魔法の理想的な並列化可能なアプリケーションを扱っています。もし私がそのようなものを作ったとしたら、私は好きなだけCPUを独占する資格があると感じます。
パトロス2009年

2

多くのスレッド(「スレッドプール」)とコアごとのスレッドの1つの例は、LinuxまたはWindowsでのWebサーバーの実装です。

Linuxではソケットがポーリングされるため、多くのスレッドが適切なタイミングで適切なソケットをポーリングする可能性が高くなりますが、全体的な処理コストは非常に高くなります。

Windowsでは、サーバーはI / O完了ポート(IOCP)を使用して実装されます。これにより、アプリケーションイベントが駆動されます。I/ Oが完了すると、OSがスタンバイスレッドを起動して処理します。処理が完了すると(通常、要求と応答のペアのように別のI / O操作で)、スレッドはIOCPポート(キュー)に戻り、次の完了を待ちます。

I / Oが完了していない場合、実行する処理はなく、スレッドは起動されません。

実際、IOCP実装では、コアあたり1つのスレッドのみをお勧めします。I / OはIOCPメカニズムに接続できます。必要に応じて、アプリケーションによってIOCが投稿される場合もあります。


あなたが話しているLinuxはわかりませんが、接続が届くまでブロックします。select()とFD_SET()と同様の関数/マクロについていくつか読むことをお勧めします。
Alexis Wilke

わかりましたので、すぐに戻る非同期フォームはありませんか?
Olof Forshell、

select()のマニュアルページから:timeout is an upper bound on the amount of time elapsed before select() returns. If both fields of the timeval structure are zero, then select() returns immediately. (This is useful for polling.) If timeout is NULL (no timeout), select() can block indefinitely.
Alexis Wilke

0

計算とメモリの観点から言えば(科学計算)4000スレッドはアプリケーションの実行を非常に遅くします。問題の一部は、コンテキスト切り替えのオーバーヘッドが非常に高く、メモリの局所性が非常に低い可能性があります。

しかし、それはあなたのアーキテクチャにも依存します。ナイアガラのプロセッサーは、ある種の高度なパイプライン技術を使用して、単一コアで複数のスレッドを処理できると想定されていると聞いたところからです。しかし、私はそれらのプロセッサーでの経験はありません。


0

これが理にかなっているといいのですが、CPUとメモリの使用率を確認し、しきい値を設定します。しきい値を超えた場合は、新しいスレッドの作成を許可しないでください。それ以外の場合は許可してください...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.