2009-06-01 12 views
41

科学計算のほとんどの人は、共用メモリの並列化に関して準標準としてOpenMPを使用しています。パラレル化:pthreadsまたはOpenMP?

OpenMP over pthreadsを使用する理由は何ですか(可読性を除く)?後者はもっと基本的なようだし、最適化するのが早くて簡単かもしれないと思う。

答えて

37

基本的には、並列化でどのレベルの制御をしたいのかが分かります。 OpenMPは、いくつかの#pragmaステートメントを追加し、コードの並列バージョンをすばやく作成することだけが目的です。 MIMDコーディングや複雑なキューイングで本当に面白いことをしたいのであれば、OpenMPでこれをすべて実行することはできますが、その場合はスレッドを使う方がはるかに簡単です。 OpenMPは、pthreadsと同様に、異なるプラットフォーム用のコンパイラが多数サポートされているので、移植性にも同様の利点があります。

あなたは本当に正しいです。並列化を細かく制御する必要がある場合は、pthreadsを使用してください。できるだけ少ない作業で並列化したい場合は、OpenMPを使用してください。

どちらの方法で行っても、幸運を祈ることができます。

20

その他の理由:OpenMPはタスクベースで、Pthreadsはスレッドベースです。これは、OpenMPがコアの数と同じ数のスレッドを割り当てることを意味します。だからスケーラブルソリューションを取得します。生のスレッドを使ってそれを行うのは簡単ではありません。

2番目の意見:OpenMPは、スレッドで部分的な結果を計算して結合する必要があるときに、削減機能を提供します。 1行のコードを使って実装することができます。しかし、生のスレッドを使用すると、より多くの仕事をする必要があります。

あなたの要件について考えてみてください。OpenMPは十分ですか?あなたは多くの時間を節約します。

+0

は、ソリューションのスケーラビリティについて詳しく説明してください。スケーラビリティはコンパイル時にのみ適用されるのか、それとも実行時に決定されますか?または、実行時スケーラビリティはスレッドでのみ実行できますか? – awiebe

+1

コンパイル時または実行時に作成されるスレッドの数を設定できます。実行時に番号を設定する場合は、環境変数numthreadsを使用してスレッドの数を設定することができます。実行するアーキテクチャに応じて適切な数値に簡単に設定できます。 –

+0

この回答は理にかなっていません。 OpenMPは、POSIXスレッドと同様にスレッドモデルです。 OpenMPは最初のいくつかのバージョンのタスクも持っていませんでした。 – Jeff

6

OpenMPには、それをサポートするコンパイラが必要であり、プラグマで動作します。これの利点は、OpenMPをサポートしないでコンパイルするとき(例えば、PCCやClang/LLVMなど)は、コードがコンパイルされることです。また、what Charles Leiserson wrote about DIY multithreadingをご覧ください。

Pthreadsはライブラリ用のPOSIX標準(IEEE POSIX 1003.1c)ですが、OpenMP specificationsはコンパイラで実装されます。つまり、OpenBSD rthreads、NPTLなどのさまざまなpthread実装やOpenMPをサポートするいくつかのコンパイラ(たとえば-fopenmpフラグ付きのGCC、MSVC++ 2008)があります。

Pthreadは、複数のプロセッサが使用可能な場合、およびコードが使用可能なプロセッサ数に合わせて最適化されている場合にのみ、並列化に有効です。その結果、OpenMPのコードはより簡単にスケーラブルになります。 OpenMPでコンパイルしたコードとpthreadを使ってコードを混在させることもできます。

+1

この回答の最後の段落は、すべての種類が間違っています。 – Jeff

2

質問は「私はCまたはアセンブリをプログラムするべきか?」という質問に似ています.CはOpenMPであり、アセンブリはpthreadsです。

pthreadsを使用すると、アルゴリズムとハードウェアに非常に厳密に調整された、より良い並列化が可能になります。しかしこれは多くの仕事になります。

pthreadを使用すると、並列性の低いコードを作成する方がずっと簡単です。あなたが並列に同じタスク(つまり、複数のデータに対して、である)、SIMDマシンの種類(単一命令複数データ)を実行する必要がある場合

+0

これは、OpenMPがPthreadsを使用して実装されていることを前提としています。これは必須ではありませんが、一般的には真です。 OpenMPが特化したアーキテクチャでベアメタルに実装されていれば、Pthreadsよりも速くなる可能性があります。 – Jeff

+0

@ジェフ私はそれを前提としておらず、私の答えはインプリメンテーションのdetails.OpenMPとCの独立したものであり、pthreadsとアセンブリよりも "高レベル"です。だからこそ、私はCとOpenMPがどのように実装されていても、私の両声明は真実であると信じています。 – steffen

+0

OpenMPの構文上の単純さと、実行時の意味的な負担とを混同しているようです。 [POSIXスレッド仕様](http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread.h.html)と[OpenMP 4仕様](http://www.openmp.org/)を比較しましたか? mp-documents/OpenMP4.0.0.pdf)?特に、 'pthread_create()'と 'pragma omp parallel {}'に必要なことを考えましたか? – Jeff

0

OpenMPのが理想的です。

Pthreadは、あるスレッドでデータを読み取り、別のスレッドでユーザーとやり取りするなど、(非常に異なる)タスクを並列に実行する場合に必要です。

は、このページを参照してください:

http://berenger.eu/blog/c-cpp-openmp-vs-pthread-openmp-or-posix-thread/

+0

OpenMPは常にデータの並列処理以上をサポートしています。実際にOpenMPについて理解していますか? – Jeff

0

はpthreadsの上でのOpenMPを使用するには、(読みやすさ以外の)いかなる理由がありますか?

マイクは一種のこの時に触れた:

のOpenMPは、異なるプラットフォーム用のコンパイラの多くは

Crypto++があるのpthreadsのように、今、それをサポートするという点で、可搬性に同様の利点を持っていますクロスプラットフォーム、Windows、Linux、OS X、およびBSDでの実行を意味します。モジュラ累乗やモジュラ乗算(並行演算を実行できる場所)など、オペレーションが高価になる可能性のある場所でスレッドサポートをOpenMPで実行します。

Windowsはpthreadsをサポートしていませんが、現代のWindowsコンパイラはOpenMPをサポートしています。したがって、非* nixへの移植性を望むなら、OpenMPはしばしば良い選択です。


とマイクも指摘したように:あなたがしたいすべてがいくつかの#pragma文を追加して、非常にすぐにあなたのコードの並列バージョンをお持ちであれば

OpenMPのは素晴らしいです。以下

暗号++はRSA signatures and Rabin-Williams signatures...にバーンスタインによって記載されるように微調整ルーツを用いラビンウィリアムズ署名に使用されるいくつかの値を事前計算の例である:

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); 
    } 
} 

それはマイクの観測とフィット - 微粒子制御と同期しました本当に必要ではありません。実行を高速化するために並列化が使用され、同期はソースコードで無償で行われました。

との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); 
関連する問題