2013-02-03 15 views
42

OpenMP 4.0には、 "omp simd"という新しい構造が導入されています。古い "parallel for"よりもこの構文を使用する利点は何ですか?それぞれが他のものより優れた選択肢となるのはいつですか?Parallel for vs omp simd:それぞれをいつ使うのですか?

EDIT: SIMD指令に関連する面白いpaperがあります。

+0

openmpはSIMD uintilバージョン3.0でしたが、その概念を削除しました。新しいプラグマは、SIMDのいくつかの側面に依存する古いコードとの下位互換性のためです。 openmpのドキュメントには、それについて何か言いたいことはありませんか? –

+4

これは 'parallel simd'ではありません。あなたは 'parallel' _or_ 'simd'を使います。これは、この区別を示唆しています。下記参照。 –

+0

@JD:それはもちろん、タイプミスでした。固定、ありがとう –

答えて

32

連結-に標準は、比較的明確である(P 13、行19 + 20)

任意のスレッドは、SIMD構築物に遭遇すると、構築物に関連した ループの反復がで実行することができますSIMDレーン がスレッドで使用可能です。

SIMDはサブスレッドのものです。より具体的には、simdディレクティブを使用して、のベクトル化を個別に同じスレッドに属するループ反復のチャンクを要求すると想像することができます。これは、プラットフォームに依存しない単一のマルチコアプロセッサ内に存在する複数レベルの並列処理を実現しています。このintel blog postに関する議論(アクセラレータのものと一緒に)を見てください。

基本的には、omp parallelを使用して別のスレッドに作業を配布し、複数のコアに移行できます。各コア内でベクトルパイプライン(例えば)を使用するには、omp simdを使用することが望ましいでしょう。通常omp parallelは、より粗く並行した作業の配布を扱うために「外側」に行き、omp simdは細かい並列処理を利用するために内部のタイトなループを回ります。

33

単純な答え:

OpenMPのが唯一の複数のコアのために複数のスレッドを活用するために使用。この新しいsimd拡張では、SIMD命令をIntelのAVX/SSEやARMのNEONなどの最新のCPUで明示的に使用することができます。

(SIMD命令はシングルスレッドとシングルコアで設計されていますが、SIMDの意味はGPGPUではかなり拡張できますが、GPGPUを考慮する必要はありませんOpenMP 4.0の場合)

SIMD命令を知ったら、この新しい構造を使用できます。現代のCPUで


、大きく3つの並列の種類がある:(1)命令レベルの並列性(ILP)、(2)スレッドレベルの並列性(TLP)、及び(3)SIMD命令(我々がこれはベクトルレベルかそうであると言うことができます)。

ILPは、アウトオブオーダーのCPUまたはコンパイラによって自動的に実行されます。 OpenMPのparallel forと他のスレッドライブラリを使用してTLPを利用することができます。ですから、SIMDはどうですか?コンパイラの自動ベクトル化だけでなく、コンパイラの組み込み関数も使用していました。 OpenMPのsimdは、SIMDを使用する新しい方法です。

は、非常に単純な例を取る:

for (int i = 0; i < N; ++i) 
    A[i] = B[i] + C[i]; 

上記のコードは2つのN次元ベクトルの和を計算します。簡単にわかるように、配列A[]には(loop-carried) data dependencyがありません。このループはembarrassingly parallelです。

このループを並列化する方法は複数あります。たとえば、OpenMP 4.0までは、parallel for構造体を使用してこれを並列化できます。各スレッドは複数のコアでN/#threadの繰り返しを実行します。

しかし、このような単純な追加のために複数のスレッドを使用することは、過剰なものになると考えるかもしれません。そのためベクトル化があります。これは主にSIMD命令で実装されています。 SIMDを使用

は次のようになり:

for (int i = 0; i < N/8; ++i) 
    VECTOR_ADD(A + i, B + i, C + i); 

このコードは、(1)SIMD命令(VECTOR_ADD)は256ビットまたは8ウェイ(8 * 32ビット)であると仮定します。 (2)Nは8の倍数です。

8方向SIMD命令は、1つのマシン命令でベクトル内の8つの項目を実行できることを意味します。インテルの最新のAVXは、8ウェイ(32ビット* 8 = 256ビット)のベクタ命令を提供しています。

SIMDでは、まだ1つのコアを使用しています(もう一度、これはGPUではなく従来のCPUのみです)。しかし、ハードウェアで隠された並列処理を使用することができます。現代のCPUは、各SIMD レーンを並列に実行できるSIMD命令のためにハードウェアリソースを専用にします。

スレッドレベルの並列処理を同時に使用できます。上記の例は、さらにparallel forによって並列化することができます。

(ただし、実際に何回ループをSIMDizedループに変換できるかは疑問ですが、OpenMP 4.0の仕様は少し不明なようですので、実際のパフォーマンスと実際の制限は実際のコンパイラの実装に依存します)。要約する


simd構築物はあなたがSIMD命令を使用することができ、順番に、より多くの並列処理は、スレッドレベルの並列処理と一緒に活用することができます。しかし、私は実際の実装が重要だと思います。

+2

"しかし、OpenMP 4.0のGPGPUを考慮する必要はないと思います。実際、OpenMP 4.0ではGPGPU(および他の種類のアクセラレータ)のサポートが提案されていますが、別の[TR](http://www.openmp.org/mp-documents/TR1_167.pdf)、主文の一部ではない(SC'12会議が開催された時の主なレビューテキストに含まれるように、テキストが必要に応じて磨かれていなかったためだと思います)。 –

+0

これはとても良い情報です。 – minjang

+0

"SIMD命令を使用できるSIMD構造"は、SIMD命令を使用しないSIMD命令を使用しないことを誤って暗示しています。 – Jeff

1

コンパイラは、simd句の存在を条件として並列領域内のsimd最適化を行う必要はありません。私がよく知っているコンパイラは、以前と同じ方法でネストループ、パラレルアウター、ベクタインナーを引き続きサポートしています。
これまで、OpenMPディレクティブは外部並列化ループ(collapse節付きの複数ループ)を含むループスイッチングの最適化を防ぐために行われました。これはいくつかのコンパイラで変更されたようです。 OpenMP 4は、omp parallel do [for] simdが設定されているときに、一種のストリップマイニングによって、ベクトル化できない内部ループを持つ並列外部ループの最適化を含む新しい可能性を開きます。 ifortがなくてもifortが外側ループのベクトル化として報告することがあります。これは、simpベクトルの幅よりも多くのスレッドを必要とすると思われるomp parallel do simdよりも少ないスレッド数で最適化することができます。このような違いは、simd句がないと、コンパイラに暗黙的に100または300などのループカウントを最適化するように要求されるため、simd句が無条件のsimd最適化を要求するため、推測できます。 gcc 4.9 simpのためのomp parallelは、24コアのプラットフォームを持っていたときに非常に効果的でした。

関連する問題