3

私は C++ でスレッド化を学ぼうとしていますが、それについていくつか質問がありました (より具体的には<thread>.

このコードが実行されるマシンに 4 つのコアがあるとしましょう。操作を 4 つのスレッドに分割する必要がありますか? 4 スレッドではなく 8 スレッドを作成すると、4 コアのマシンで実行速度が遅くなりますか? プロセッサにハイパースレッディングがある場合、スレッドを物理コアまたは論理コアの数と一致させる必要がありますか?

マシンが持つコアの数を気にせず、できるだけ多くのスレッドを作成するようにすべきでしょうか?

これらの質問がすでに回答されている場合は申し訳ありません。c11 で導入された を使用したスレッド化に関する情報を探していた<thread>ので、あまり見つけることができませんでした。

問題のプログラムは、多くの独立したシミュレーションを実行します。

誰かが<thread>一般的なマルチスレッドについて、または単に洞察を持っている場合は、喜んで聞いてください。

4

6 に答える 6

6

I/O なしで純粋な計算を実行し、それらの計算が独立しており、別のスレッドで行われている他の計算の結果に依存していない場合、そのようなスレッドの最大数はコアの数にする必要があります (システムには他のタスクもロードされます)。

ネットワーク I/O などを行っている場合は、より多くのスレッドを使用できる可能性があります。

ディスク I/O を実行している場合は、多くの場合、ディスクからのシングル スレッド読み取りが最適です。複数のスレッドからディスクを読み取ると、ディスク上で読み取り/書き込みヘッドが移動し、処理が遅くなるからです。

コードを単純にするためにスレッドを使用している場合、スレッドの数はおそらく何をしているかによって異なります。

また、各スレッドがどの程度「自立」しているかにも依存します。複雑な方法でデータを共有する必要がある場合、他のスレッドなどの共有/待機により、スレッドが増えると速度が低下する可能性があります。

他の人が言ったように、この柔軟なフレームワークを作成し、さまざまなオプションをテストしてください。できれば複数のマシンで (コードを実行するマシンが 1 種類しかない場合を除きます)。

于 2013-05-23T23:28:11.203 に答える
3

つまり、C++11 で導入されたスレッド サポート ライブラリのようなものはありません<threads.h><thread>

あなたの質問に対する唯一の答えは、「テストして見てください」です。Nパラメーターを渡すことで実行できるように、コードを十分に柔軟にすることができます (Nは目的のスレッド数です)。

CPU バウンドの場合、答えは IO バウンドの場合とは大きく異なります。

だから、テストして見てください!参考までに、このリンクが役立ちます。そして、あなたが本気なら、この本を手に入れてください。マルチスレッド、同時実行性などは、毛むくじゃらのトピックです。

于 2013-05-23T23:22:14.390 に答える
2

実行しているマシンと比較して、必要なスレッドの数を考えないでください。スレッド化は、次のようなプロセスがある場合はいつでも価値があります。

A: 残りのプロセスを待つ必要のない、非常に遅い操作があります。

B: 特定の関数は他の関数よりも高速に実行でき、インラインで実行する必要はありません。

C: 順序に依存しない I/O が大量に発生しています (Web サーバー)。

これらは、スレッドの起動が理にかなっている場合の明らかな例のほんの一部です。したがって、起動するスレッドの数は、実行する予定のアーキテクチャよりも、コードでポップアップするこれらのシナリオの数に大きく依存します。実際、本当に最適化が必要なプロセスを実行していない限り、起動するスレッドの数と比較してアーキテクチャのベンチマークを行っても、数パーセントの追加パフォーマンスしか得られない可能性があります。現代のコンピューターでは、この数はまったく変化しないはずです。

I/O の例を見てみましょう。これが最もメリットが得られるシナリオです。あるプログラムが、ネットワークを介して 200 人のユーザーと対話する必要があると仮定しましょう。ネットワーク I/O が非常に遅い。CPU より数千倍遅い。各ユーザーを順番に処理する場合、最初のユーザーからのデータを待つだけで数千のプロセッサ サイクルが無駄になります。一度に複数のユーザーからの情報を処理できなかったのでしょうか? この場合、約 200 人のユーザーがいて、待機しているデータは、処理できるよりも数千倍遅いことがわかっているため (このデータに対して実行する処理の量が最小限であると仮定して)、次のようにする必要があります。オペレーティング システムが許可する限り多くのスレッドを起動します。

次に、I/O 集約度の低い例を考えてみましょう。いくつかの関数が順番に実行されますが、互いに独立しており、そのうちのいくつかはより高速に実行される可能性があります。たとえば、ディスク I/O が 1 つにあり、別のディスク I/O。この場合、I/O は依然としてかなり高速ですが、ディスクが追いつくのを待って処理時間を浪費することは間違いありません。そのため、処理能力を活用し、無駄なサイクルを最小限に抑えるために、いくつかのスレッドを起動できます。ただし、オペレーティング システムで許可されている限り多くのスレッドを起動すると、分岐予測などのメモリ管理の問題が発生する可能性があります。この場合、あまりにも多くのスレッドを起動すると、実際には最適ではなく、プログラムの速度が低下する可能性があります。ここでは、マシンに搭載されているコアの数について言及していないことに注意してください。異なるアーキテクチャ向けの最適化はそうではありません。価値はありますが、1 つのアーキテクチャを最適化すると、ほとんどのアーキテクチャで最適に近づく可能性があります。繰り返しますが、合理的に最新のすべてのプロセッサを扱っていると仮定します。

于 2013-05-23T23:25:19.137 に答える
2

このコードが実行されるマシンに 4 つのコアがあるとしましょう。操作を 4 つのスレッドに分割する必要がありますか?

コードの一部を並行して実行できる場合は、高速化できますが、スレッドのロードとスレッド間でのデータの切り替えには非常に時間がかかるため、これは非常に困難です。

4 スレッドではなく 8 スレッドを作成すると、4 コアのマシンで実行速度が遅くなりますか?

それは、それがしなければならないコンテキストの切り替えに依存します。実行がスレッド間で非常に頻繁に切り替わることもあれば、そうでないこともありますが、これを制御するのは非常に困難です。いずれの場合も、同じ作業を行う 4 つのスレッドよりも速く実行されることはありません。

プロセッサにハイパースレッディングがある場合、スレッドを物理コアまたは論理コアの数と一致させる必要がありますか?

ハイパースレッディングは、より多くのコアを持つ場合とほぼ同じように機能します。実際のコアと実行コアの違いに気付くと、警告を回避するのに十分な知識が得られます。

マシンが持つコアの数を気にせず、できるだけ多くのスレッドを作成するようにすべきでしょうか?

いいえ、スレッドは管理が難しいため、できるだけ避けてください。

問題のプログラムは、多くの独立したシミュレーションを実行します。

openmpを調べる必要があります。プログラムを分割できる場合に計算を並列化するために作成された C のライブラリです。並列と並行を混同しないでください。同時実行は単に複数のスレッドが一緒に動作することであり、並列はアプリケーションを高速化するために特別に作成されます。おそらく、openmp はやり過ぎかもしれませんが、並列コンピューティングに近づいているときに知っておくとよいでしょう。

于 2013-05-23T23:26:38.597 に答える
1

ほとんどの人は、大規模なスレッド プロジェクトは c++ 以外の言語 (go、scala、cuda) でサポートされていると言うでしょう。データの並列処理とは対照的に、タスクの並列処理は c++ でより適切に機能します。実行するタスクと同じ数のスレッドを作成する必要があると思いますが、データの並列処理が問題に関連している場合は、cuda を使用して後でプロジェクトの残りの部分にリンクすることを検討してください。
注: ある種のシステム モニターを見ると、8 つをはるかに超えるスレッドが実行されている可能性が高いことがわかります。私のコンピューターを見てみると、一度に数百のスレッドが実行されていたので、オーバーヘッドについてあまり心配する必要はありません。私が他の言語について言及することを選択した主な理由は、c++ または c で多くのスレッドを管理するのは非常に困難でエラーが発生しやすい傾向があるためです。 t)

于 2013-05-23T23:19:12.860 に答える
0

ハイパースレッディングに関して、私が経験から発見したことについてコメントさせてください。

大規模な密行列乗算では、ハイパースレッディングは実際にはパフォーマンスを低下させます。たとえば、Eigen と MKL はどちらも OpenMP (少なくとも私が使用した方法) を使用しており、4 つのコアと 8 つではなく 4 つのスレッドのみを使用するハイパースレッディングを備えたシステムでより良い結果を得ることができます。また、Eigen よりも優れたパフォーマンスを得る私自身の GEMM コードでは、8 スレッドではなく 4 スレッドを使用した方が良い結果が得られます。

ただし、私のマンデルブロー描画コードでは、OpenMP でハイパースレッディングを使用すると (4 スレッドではなく 8 スレッド)、パフォーマンスが大幅に向上します。一般的な傾向 (これまでのところ) ではschedule(static)、OpenMP を使用してコードが適切に機能する場合、ハイパースレッディングは役に立たず、さらに悪化する可能性があります。コードがうまく機能する場合はschedule(dynamic)、ハイパースレッディングが役立つ場合があります。

言い換えれば、これまでの私の観察では、各スレッドの実行時間が大幅に変化する可能性がある場合、ハイパースレッディングが役立つということです。各スレッドの実行時間が一定である場合、パフォーマンスが低下することさえあります。ただし、ケースごとにテストして確認する必要があります。

于 2013-05-24T14:15:40.373 に答える