2013-07-10 12 views
7

C - determine if a number is primeに基づいて基本的な素数チェッカーを作成しますが、OpenMPを使用しています。 OpenMPを使用した「無効な制御述部」コンパイラエラー

int isPrime(int value) 
{ 
    omp_set_num_threads(4); 

    #pragma omp parallel for 
    for(int j = 2; j * j <= value; j++) 
    { 
    if (value % j == 0) return 0; 
    } 
    return value; 
} 

-fopenmpでコンパイル、GCCバージョン4.7.2は、forループに対してinvalid controlling predicateを述べ、erroringれます。

このエラーは、forループのjの2乗に起因するようです。私はこれを回避し、アルゴリズムからの望ましい出力を達成する方法がありますか?

+0

open mpループの構文でreturn文が使用できることを確かめていますか? – alexbuisson

+0

残念ながら、OpenMPを使用してループを並列化することは、トライアル部門があるプライムプライムのテストでは役に立ちません。ただし、試行分割を使用して複数の素数をテストする場合に効果的に使用できます。しかし、素数のリストを見つけるために、私はエラトステネスのふるいをお勧めします。 OpenMPを使ったバージョンhttp://create.stephan-brumme.com/eratosthenes/ –

+0

また、 'isPrime'関数で' j * j <= value'の代わりに 'j <= j/value'を使うことをお勧めしますオーバーフローする可能性がありますhttp://rosettacode.org/wiki/Primality_by_trial_division#C –

答えて

8

returnは、中括弧の前に終了するためループ内では使用できません。

注定義は以下の通り:OpenMPのV2.5仕様から

、1.2.2 OpenMPの言語の用語、P2:17〜

構造ブロック - C/C++の場合、実行文を、可能であれば 化合物で、上部に単一エントリ、下部に 下部に単一の出口があります。

構造化ブロックは、オープン{で始まり、終了コード}で終了します。 returnはこれらの中括弧内に含まれ、それは2つの出口(ブレースによる出口でreturnに1つずつ)

OpenMPのは、以下の5つの制限を配置しているため、このプログラムはまた、構造化ブロックのためのOpenMP定義に違反しています

  • ループ変数は符号付き整数でなければなりません。 DWORDなどの符号なし整数 は機能しません。
  • 比較動作がフォームloop_variable <<=>、 又は>= loop_invariant_integer
  • でなければならないループの3番目の式またはの増分部分は 整数加算または整数減算のいずれかで、ループ不変 によってなければなりません値。比較演算が<または<=であれば、比較 操作が>>=であれば
  • 、ループ変数は 反復ごとに増加し、逆に、ループ変数は、すべての 繰り返しで増減しなければならない必要があります。
  • ループは、 の内部からループへのジャンプが許可されていないことを意味する基本ブロックでなければなりません。出口の ステートメントはアプリケーション全体を終了します。ステートメント gotoまたはbreakが使用されている場合は、ループ内でジャンプしなければなりません。 の外側にジャンプする必要はありません。例外処理の場合も同じです。ループ内で例外をキャッチする必要があります。
+0

ループ変数に署名する必要がある理由がわかりません。符号付き8バイトより大きい整数が必要な場合はどうなりますか? – Nubcake

2

OpenMP標準(§2.5.1、p。

  • VARリレーショナル・オプ・B、及び
  • Bリレーショナル演算VAR

のご利用:40)、forループの制御述語の許容される形態でありますj * j <= valueは、この要件の明確な違反です。その根拠は、実行時にvalueの整数平方根を計算するコードをコンパイラが発行する必要があり、後者はvalueの値、特に負の値については未定義です。

あなたはsqrt_valuevalueの整数平方根であるが、その後、ループ内の構造化されたブロックで代替出口経路を持つ問題が来るところ、j <= sqrt_valuej * j <= valueを置き換えることができます。残念なことに、この場合、OpenMPは並列ループの早期終了をサポートしていないため、簡単な解決策はありません。

関連する問題