web-dev-qa-db-ja.com

並列化:pthreadまたはOpenMP?

科学計算のほとんどの人は、共有メモリの並列化に関して、準標準としてOpenMPを使用しています。

Pthread上でOpenMPを使用する理由(読みやすさ以外)はありますか?後者はより基本的なようで、最適化がより速く、より簡単になると思います。

44
hanno

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

したがって、あなたは絶対に正しいです-並列化を微調整する必要がある場合は、pthreadを使用してください。できるだけ少ない作業で並列化する場合は、OpenMPを使用します。

どちらに行くにしても、頑張ってください!

41
Mike

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

セカンドオピニオン:OpenMPは削減機能を提供します:スレッドで部分的な結果を計算してそれらを組み合わせる必要がある場合。 1行のコードを使用するだけで実装できます。しかし、生のスレッドを使用すると、より多くの仕事をする必要があります。

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

23

OpenMPには、それをサポートし、プラグマで動作するコンパイラが必要です。これの利点は、OpenMPサポートなしでコンパイルする場合(現在のPCCやClang/LLVMなど)、コードがコンパイルされることです。また、 Charles LeisersonがDIYマルチスレッドについて書いたこと もご覧ください。

PthreadsはライブラリのPOSIX標準( IEEE POSIX 1003.1c )ですが、 OpenMP仕様 はコンパイラに実装されます。そうは言っても、さまざまなpthread実装(OpenBSD rthreads、NPTLなど)と、OpenMPをサポートするコンパイラー(-fopenmpフラグ付きのGCC、MSVC++ 2008など)があります。

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

8
Anonymous

あなたの質問は「Cまたはアセンブリをプログラムする必要があるか」という質問に似ています。CはOpenMPであり、アセンブリはpthreadです。

Pthreadを使用すると、はるかに優れた並列化を実行できます。つまり、アルゴリズムとハードウェアに非常に厳密に調整されます。ただし、これは大変な作業になります。

Pthreadを使用すると、並列化が不十分なコードを作成することもはるかに簡単になります。

3
steffen

Pthread上でOpenMPを使用する理由(読みやすさ以外)はありますか?

マイクはこれに少し触れました:

OpenMPには、pthreadと同様に、さまざまなプラットフォーム用の多くのコンパイラーがOpenMPをサポートするという点で、移植性において同様の利点があります。

Crypto ++ はクロスプラットフォームです。つまり、Windows、Linux、OS X、およびBSDで実行されます。べき乗剰余やモジュラー乗算など、操作にコストがかかる可能性がある場所(および同時操作を実行できる場所)でのスレッドサポートにOpenMPを使用します。

Windowsはpthreadをサポートしていませんが、最新のWindowsコンパイラはOpenMPをサポートしています。したがって、* nix以外への移植性が必要な場合は、OpenMPが適していることがよくあります。


そしてマイクも指摘したように:

OpenMPは、いくつかの#pragmaステートメントを追加し、コードの並列バージョンを非常に迅速に作成するだけの場合に最適です。

以下は、Bernsteinが RSA署名とRabin-Williams署名... で説明しているように、TweakedRootsを使用してRabin-Williams署名で使用されるいくつかの値を事前計算するCrypto ++の例です。

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がnotで使用できる場合、コードは次のようになります。

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);
1
jww

OpenMPは、同じタスクを並行して(つまり、複数のデータに対して)、一種のSIMDマシン(単一命令の複数データ)で実行する必要がある場合に理想的です。

Pthreadは、たとえば、あるスレッドでデータを読み取ったり、別のスレッドでユーザーと対話したりするなど、(まったく異なる)タスクを並行して実行する場合に必要です。

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

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

0
user1284631

タスクベースのプログラムの共有メモリにはOpenMPが選択されています。スレッドベースのプログラムの場合、pthreadが使用されます。 Pthreadsは、プログラミング言語の点ではC/FORTRANに似ています。つまり、OpenMPはJavaまたはPythonであり、手元に多くの制御があります。簡単な解決策を提供しますが、私たちが利用できる制御はあまりありません。

0
Abinav Ravi