2017-01-26 11 views
1

私はOpenMPと並列化を全く新しくしています。この問題は非常にシンプルですが、その原因や解決策を探す方法がわかりません。私のコードは次のようになります。また、FindPrimeを呼び出して、その数が素数であるかどうかをチェックするisPrime主な機能はありOpenMPが変数を正しく宣言しています

int FindPrime(int size) { 
    long long next_p = 2; 
    #pragma omp parallel \ 
     shared(next_p,size) 
    long long tid = omp_get_thread_num(); 
    long long tnum = omp_get_num_threads(); 
    for(int long long i = tid; i < size; i=i+tnum) { 
     long long j; 
     j=next_p+1; 
     while (!IsPrime(j)) { 
      j++; 
     } 
     next_p = j; 
    } 
    return next_p; 
} 

私はグラムで、このコードをコンパイルしてみてください++とフラグ-fopenmp-lpthread、私は結果の行に

for(int long long i = tid; i < size; i=i+tnum){ 

を指し

error: 'tid' was not declared in this scope 

を得ることは、それだけで文句と私にも奇妙です約tidであり、tnumではありません。これもOpenMP関数からのものです。

+0

'parallel'領域のスコープを定義する' {'と'} 'を追加します – Gilles

+0

OpenMPランタイムライブラリの関数は他の関数と同じように機能します。これらは並列領域や他のOpenMP構造体の外部で呼び出すこともできます。 –

答えて

1

あなたが直面する問題は、あなたが書いたparallel指示の範囲に由来します。あなたはその範囲を定義するブロックを作成するために{}を使用していないので、この1は、明らかに、すなわち

long long tid = omp_get_thread_num(); 

だからあなたtid変数は今だけ1行の範囲を持って、それを次の一行に制限されています(その宣言)、したがって、ループをforループで使用する場合は宣言しません。問題を解決するには

、あなただけのように、並列ブロックをマークする{}を追加する必要があります。

int FindPrime(int size) { 
    long long next_p = 2; 
    #pragma omp parallel shared(next_p,size) 
    { // start of the parallel block 
     long long tid = omp_get_thread_num(); 
     long long tnum = omp_get_num_threads(); 
     for(long long i = tid; i < size; i=i+tnum) { 
      long long j; 
      j=next_p+1; 
      while (!IsPrime(j)) { 
       j++; 
      } 
      next_p = j; 
     } 
    } // end of the parallel block 
    return next_p; 
} 

この方法で、あなたのコードは並列化されます。しかし、私はそれが何をすべきかはわかりませんが、私はそれがあなたが期待していることをしないと確信しています...実際には、スレッド間のnext_pの更新に関する競争条件があります。あなたのアルゴリズムを考え直すべきだと思う。

最後に、forループを並列化する方法は、#pragma omp for schedule(static, 1)とまったく同じです。このアプローチに固執したい場合は、おそらくそれを使用することを検討する必要があります。

+0

あなたの詳細で有益な答えをありがとう。コードをコンパイルして実行したら、実際に競合状態が見つかったので、この問題について別の方法でやり遂げました。私はループのためのompについて聞いたことがありますが、スケジュールは私には新しいものです。洞察に感謝します。 – theupandup

+0

OpenMP仕様では、実行可能な指令の範囲を中括弧で囲む必要はありません。 _ "**構造化ブロック** - C/C++の場合、実行可能な文(複合語、上部に単一のエントリ、下部に単一の出口、またはOpenMP構造体を持つ可能性があります)" _ OPのコードは有効ですOpenMP、しかし、並列領域は指令に続く単一の文で構成されています。 –

+0

前のコメントは、あなたのステートメント_ "...(これはBTW非標準であり、あなたのコンパイラによって間違っていると報告されているはずです)..." _、これは間違っています。 –

関連する問題