並列化:pthreads または OpenMP?
-
06-09-2019 - |
質問
科学技術コンピューティングの分野のほとんどの人は、共有メモリの並列化に関して準標準として OpenMP を使用しています。
pthread 上で OpenMP を使用する理由は (読みやすさ以外に) ありますか?後者の方がより基本的であり、最適化がより速く簡単に行えるのではないかと思います。
解決
これは、基本的に、あなたの並列化を介したいコントロールのどのレベルに沸きます。やりたいことがいくつかの#pragma文を追加して、非常にすぐにあなたのコードの並列バージョンをお持ちの場合はOpenMPのは素晴らしいです。あなたはMIMDコーディングや複雑なキューイングと、本当に面白いことをしたい場合、あなたはまだのOpenMPですべてこれを行うことができますが、おそらく、その場合には、スレッドを使用して多くの方が簡単です。 OpenMPのは、異なるプラットフォーム用のコンパイラの多くはpthreadsのと同じように、今、それをサポートするという点で、可搬性に同様の利点を持っています。
だから、絶対に正しいです - あなたは、並列オーバー微調整制御が必要な場合は、pthreadsを使用します。あなたは、できるだけ作業を並列化したい場合は、OpenMPのを使用します。
あなたが行くことに決めるどちらの方法で、幸運を!
他のヒント
もう一つの理由:OpenMPのはタスクベースで、Pthreadsのは、スレッドベースです。これは、OpenMPは、コア数とスレッドの同じ数を割り当てることを意味します。だから、のスケーラブルのソリューションを取得します。生のスレッドを使用してそれを行うにはそれほど簡単な作業ではありません。
セカンドオピニオン:OpenMPのは、還元機能を提供します。あなたは、スレッドでの部分的な結果を計算し、それらを結合する必要がある場合。あなただけの単一のコード行を使用して、それを実装することができます。しかし、あなたはより多くの仕事を行う必要があり、生のスレッドを使用します。
ちょうどあなたの要件を考えると理解しよう:OpenMPのは、あなたのための十分なのですか?あなたは多くの時間を節約します。
のOpenMPは、それをサポートするコンパイラを必要とし、プラグマで動作します。これの利点は、OpenMPサポート(例えば、PCC又は今のようなクラン/ LLVM)なしでコンパイルするとき、コードはまだコンパイルすることです。また、何チャールズを見てLeisersonはDIYマルチスレッディングについて書いています。
のPthreadは、POSIX規格である( IEEE POSIX 1003.1cする)コンパイラに実装されるの図書館、しばらく OpenMPの仕様については、それは、pthreadの実装(例えば、OpenBSDのrthreads、NPTL)の様々な、およびOpenMPの(-fopenmpフラグを例えばGCC、MSVC ++ 2008)をサポートするコンパイラの数があると述べている。
のPthreadは、複数のプロセッサが利用可能であるとき、並列にのみ有効であり、コードが利用可能なプロセッサの数のために最適化されている場合のみ。 OpenMPのためのコードは、より簡単に、結果としてスケーラブルです。あなたも、pthreadsを使用してコードでのOpenMPでコンパイルコードを混在させることができます。
あなたしている質問は、質問「私はCまたはアセンブリをプログラムすべき」、Cは、OpenMPおよびアセンブリであることのpthreadであることに似てます。
のpthreadsを使用すると、はるかに優れた並列化、非常にしっかりとあなたのアルゴリズムとハードウェアに調整し、より良い意味を行うことができます。これは、しかし多くの作業になります。
のpthreadsで、不十分な並列化コードを生成するためにも非常に簡単です。
pthread 上で OpenMP を使用する理由は (読みやすさ以外に) ありますか?
マイクはこれについて次のように述べています。
OpenMP には、pthread と同様に、さまざまなプラットフォームの多くのコンパイラが OpenMP をサポートしているという点で、移植性の面でも同様の利点があります。
クリプト++ クロスプラットフォームとは、Windows、Linux、OS X、BSD 上で動作することを意味します。OpenMP は、べき乗剰余や乗算剰余など、演算にコストがかかる場所 (および同時演算が実行できる場所) でのスレッド サポートに OpenMP を使用します。
Windows は pthread をサポートしていませんが、最新の Windows コンパイラは OpenMP をサポートしています。したがって、非 *nix への移植性が必要な場合は、OpenMP が良い選択となることがよくあります。
そしてマイクも次のように指摘しました。
OpenMP は、いくつかの #pragma ステートメントを追加してコードの並列バージョンをすばやく作成したい場合に最適です。
以下は、Bernstein によって説明されている調整されたルートを使用して、Rabin-Williams 署名で使用されるいくつかの値を事前計算する Crypto++ の例です。 RSA署名とラビン・ウィリアムズ署名...:
void InvertibleRWFunction::Precompute(unsigned int /*unused*/)
{
ModularArithmetic modp(m_p), modq(m_q);
#pragma omp parallel sections
{
#pragma omp section
m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8);
#pragma omp section
m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8);
#pragma omp section
m_pre_q_p = modp.Exponentiate(m_q, m_p - 2);
}
}
これは Mike の観察と一致します。きめ細かい制御と同期は実際には必要ありませんでした。実行を高速化するために並列化が使用され、ソース コードでは同期が無料で行われました。
そして、OpenMP が ない 利用可能な場合、コードは次のようになります。
m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8);
m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8);
m_pre_q_p = modp.Exponentiate(m_q, m_p - 2);
は、の同じタスクの並列に(つまり、複数のデータに対して、である)、SIMDマシンの種類(単一命令複数データ)を実行する必要がある場合OpenMPのが理想的です。
あなたは、このような、例えば、1つのスレッドでデータを読み取り、別のスレッドでユーザーと対話するように並列に(全く異なる)のタスクを実行したい場合、のPthreadが必要とされます。
このページを参照してください。
http://berenger.eu /ブログ/ C-CPP-のOpenMP-VS-pthreadの-のOpenMP - または - POSIXスレッド/ の