2017-05-26 5 views
0

大規模なネストされたループの崩壊原因のパフォーマンスについて、誰かが入札を知っているかどうか疑問に思っていましたか? 意味私はパフォーマンスOpenMPの崩壊と大規模なネストループの崩壊の比較

omp parallel for private(i,j,k) collapse(3) schedule(static)

omp parallel for private(i,j,k) schedule(static)

は、ネストされたforループ

for(int i=0; i<i_max; i++){ 
    for(int j=0; j<j_max; j++){ 
    for(int k=0; k<k_max; k++){ 
    A[i][j][k]=B[i][j][k]+C[i][j][k]; 
           } 
          } 
          } 

I_最大、J_MAXのように構築プラグマを比較したいと、すべて何かk_maxあるでしょう使用可能なスレッドの数の5〜10倍です。

私が崩壊原因を正しく理解していれば、openmpは3つのループをサイズi_max*j_max*k_maxのものに崩壊させ、(i_max*j_max*k_max) mod #threads = 0の場合は最高の性能と仮定します。

崩壊の原因がなければ、openmpはiループだけを取りますか?もしそうなら、私の次の仮定はi_max mod #threads = 0のための最良の性能を得ることであり、両方のプラグマに匹敵する性能が期待されます。

ご覧のとおり、私はここでかなり推測しています。誰かが実際にこのような場合の両方のプラグマのパフォーマンスをテストしましたか?

+0

あなたの推測は問題ありません。どちらのケースでも*あなたのパフォーマンスをテストしましたか? – Zulan

+1

このような小さなボディを持つループでは、内部ループの実装が改善されているため、スレッド数が「i_max」を分けると、折りたたまれていないバージョンが高速になることがあります(どのくらい?_itに依存します)。ループを崩壊させると、ベクトル化が阻害される可能性があります。 –

+0

@ Zulan私はいくつかのテストを行ったが、私の結果をどのように解釈するのか分からなかった。あるサーバーでは、折りたたみバージョンは高速で、別のサーバーでは非折りたたみバージョンでした。私はいくつかのシミュレーションを禁止することなく、それを広範囲にテストする能力を持っていないので、ここでいくつかの説明をしました。 – LeBo

答えて

2

ループを折り畳むと、OpenMPはそれらを1つの大きなループにします。そのループの反復空間はチャンクに分割され、有効なループスケジュールに従ってスレッド間で分割されます。個々のループ反復のスレッド数による分割可能性に応じて、チャンクに不完全な内部ループが含まれる状況になる可能性があります。たとえば、i_max,j_max、およびk_maxのいずれもがスレッド数で割り切れるものではなく、i_max * j_max * k_maxである場合があります。さらに、異なるチャンクには、不完全なループの異なる部分が含まれている可能性があります。そして、これはすべて実行時に構成可能なスレッド数に依存します。したがって、コンパイラがループのベクトル化を確実にモデル化できず、有益であるかどうかを評価することができないため、ベクトル化が禁止される可能性があります。また、ループ反復回数がベクトル長で割り切れない場合、またはデータがアライメントされていない場合に対処するシリアルループを作成する必要があります。

外部ループのみが並列である場合、コンパイラは内部ループを自由に変形することができます。たとえば、ループを安全にベクトル化できます。それが前のケースより速くなるかどうかは不明です。ベクトル化は計算性能を向上させますが、メモリサブシステムにも大きなプレッシャーを与えます。それらの比率は、利益があるかどうかを決定します。

一方、AB、およびCは、すべてのx j_maxのx k_maxi_max(とx <= x_maxはタイプミスで、実際x < x_maxでなければならないこと)であると仮定し、本当に賢いコンパイラはあなたがオーバーすべての反復処理されていることがわかりますが可能指数と基本的に2つの1次元ベクトルを合計し、X_lin[]X[][][]後ろデータの線形化1-D図である

#pragma omp parallel schedule(static) 
for (z = 0; z < i_max * j_max * k_max; z++) 
    A_lin[z] = B_lin[z] + C_lin[z]; 

のように折り畳まれたループを回します。ここでベクトル化の大きな可能性があるので、コンパイラがどれくらいの分析を行うことができるかによります。

多くの種類のハードウェアで同等に優れた性能を発揮するアルゴリズムはありません。そのため、OpenMPは環境変数で設定できる多くの調整パラメータを提供しています。また、サーバCPUとデスクトップCPUの性能を比較する場合、サーバCPUは通常、ラージレベルのキャッシュが大きく、メインメモリの帯域幅が大きいメモリチャネルが多いため、ベクトル化されたコードは大量で優れたパフォーマンスを発揮しますのデータ。

+0

はい、 '<='はタイプミスでした! あなたの精巧な答えをありがとう! – LeBo