web-dev-qa-db-ja.com

マルチコアプロセッサでスレッド割り当てをプログラムする方法は?

マルチコアプロセッサでスレッドを試してみたいと思います。 2つの異なるプロセッサコアによって実行される2つの異なるスレッドを使用するプログラムを作成します。

ただし、スレッドが異なるコアにどのレベルで割り当てられるかは、私にはわかりません。次のシナリオが想像できます(オペレーティングシステムとプログラミング言語の実装によって異なります)。

  1. スレッドの割り当ては、オペレーティングシステムによって管理されます。スレッドはOSシステムコールを使用して作成され、プロセスがたまたまマルチコアプロセッサで実行されると、OSは異なるコアに異なるスレッドを自動的に割り当て/スケジュールしようとします。
  2. スレッドの割り当ては、プログラミング言語の実装によって管理されます。異なるコアにスレッドを割り当てるには特別なシステムコールが必要ですが、プログラミング言語の標準スレッドライブラリは、その言語の標準スレッド実装を使用すると、これを自動的に処理します。
  3. スレッドの割り当ては明示的にプログラムする必要があります。私のプログラムでは、使用可能なコアの数を検出し、ライブラリ関数などを使用して異なるスレッドを異なるコアに割り当てるために、明示的なコードを記述する必要があります。

質問をより具体的にするために、マルチスレッドアプリケーションをJavaまたはWindowsまたはLinuxのC++で記述したとします。アプリケーションがマルチコアで実行されたときに、魔法のように複数のコアを表示して使用しますか?プロセッサ(すべてがオペレーティングシステムまたは標準スレッドライブラリによって管理されているため)、または複数のコアを認識するようにコードを変更する必要がありますか?

13
Giorgio

私のアプリケーションは、マルチコアプロセッサで実行されたときに複数のコアを魔法のように見て使用しますか(すべてがオペレーティングシステムまたは標準のスレッドライブラリによって管理されているため)、または複数のコアを認識するようにコードを変更する必要がありますか? ?

簡単な答え:はい、通常、オペレーティングシステムまたはスレッドライブラリによって管理されます。

オペレーティングシステムのスレッドサブシステムは、スレッドをプロセッサに優先的に割り当てます(オプション1)。つまり、スレッドが時間割り当てまたはブロックの実行を終了すると、スケジューラは次に優先度の高いスレッドを探し、それをCPUに割り当てます。詳細はオペレーティングシステムによって異なります。

つまり、オプション2(プログラミング言語で管理)とオプション3(明示的に)が存在します。たとえば、最近のバージョンの.Netのタスクライブラリとasync/awaitを使用すると、開発者は並列化可能な(つまり、それ自体と並行して実行できる)コードをより簡単に記述できます。関数型プログラミング言語は本質的に並列化可能であり、一部のランタイムは、可能であればプログラムのさまざまな部分を並列で実行します。

オプション3(明示的に)と同様に、Windowsではスレッドのアフィニティーを設定できます(スレッドが実行できるプロセッサーを指定)。ただし、これは通常、最速の応答時間重視のシステム以外では不要です。プロセッサへの効果的なスレッドの割り当ては、ハードウェアに大きく依存し、同時に実行されている他のアプリケーションに非常に敏感です。

実験したい場合は、素数のリストの生成やマンデルブロ集合の作成など、CPUを集中的に使用する長時間実行するタスクを作成します。次に、お気に入りのライブラリに2つのスレッドを作成し、両方のスレッドをマルチプロセッサマシンで実行します(つまり、ここ数年にリリースされたほぼすべてのスレッド)。両方のタスクは並行して実行されるため、ほぼ同時に完了するはずです。

11
akton