web-dev-qa-db-ja.com

コアごとの最適なスレッド数

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

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

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

256
Juliet

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

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

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

235
Gonzalo

@Gonzaloの答えに同意します。 I/Oを実行しないプロセスがありますが、これが私が見つけたものです。

enter image description here

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

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

このテストでは、最適な数はマシンのコアの数に等しくなりました。

121
Motasim

私はこの質問がかなり古いことを知っていますが、2009年以来状況は変化しています。

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

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

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

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

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

46
Alexis Wilke

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

23
Jim Garrison

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

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

18
pkazen

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

From Wikipedia

弱いスケーリング:プロセッサごとに固定された問題サイズに対して、解決時間がプロセッサの数によってどのように変化するか。

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

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

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

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

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

私は問題を単純化し、他の回答(コンテキストスイッチなど)に記載されているオーバーヘッドを無視しましたが、データサイズに応じて、利用可能なコアの数よりも多くのスレッドを用意することが有益であるという点を得られることを願っています再処理します。

7
someneat

一度に4000スレッドがかなり高くなります。

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

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

7
Earlz

基準。

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

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

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

6
mmr

マシンでプロセスの数を返す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をコンパイルする場合は、 here にあります。

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

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

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

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

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

2
Olof Forshell

スレッドがブロックされない限り、コアあたり1スレッドが理想です。

これが当てはまらない場合の1つは、コアで実行されている他のスレッドが存在する場合です。この場合、より多くのスレッドがプログラムに実行時間の大きなスライスを与える可能性があります。

2
patros

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

0
M. Gopal

計算とメモリ制限の観点(科学計算)から言えば、4000スレッドはアプリケーションの実行を本当に遅くします。問題の一部は、コンテキストスイッチングのオーバーヘッドが非常に高く、メモリローカリティが非常に低い可能性が高いことです。

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

0
Anycorn