9

OpenMP に問題があります。MSVS コンパイラは、「pragma omp atomic の形式が正しくありません」とスローします。理由がわかりません。コード: (プログラムは積分法を使用して PI 番号を指定します)

#include <stdio.h>
#include <time.h>
#include <omp.h>

long long num_steps = 1000000000;
double step;

int main(int argc, char* argv[])
{
    clock_t start, stop;
    double x, pi, sum=0.0;
    int i;
    step = 1./(double)num_steps;
    start = clock();

    #pragma omp parallel for
    for (i=0; i<num_steps; i++)
    { 
        x = (i + .5)*step;
        #pragma omp atomic //this part contains error
        sum = sum + 4.0/(1.+ x*x);  
    }

    pi = sum*step;
    stop = clock();

    // some printf to show results
return 0;
}
4

4 に答える 4

13

あなたのプログラムは、現在の OpenMP 標準 (たとえば、GCC 4.7.1 で変更せずにコンパイルされる) によって構文的に完全に正しい OpenMP コードですが、x宣言する必要があるprivate(構文ではなく意味論的なエラーです)。atomic残念ながら、Microsoft Visual C++ は非常に古い OpenMP 仕様 (2002 年 3 月の 2.0) を実装しており、次のステートメントのみをコンストラクトで許容できます。

x binop= expr
x ++
++ x
x --
-- x

それ以降のバージョンにはx = x binop exprが含まれていましたが、MSVC は VS2012 でも OpenMP バージョン 2.0 のままです。比較のために、現在の OpenMP のバージョンは 3.1 であり、今後数か月で 4.0 がリリースされる予定です。

OpenMP 2.0 では、ステートメントは次のようになります。

#pragma omp atomic
sum += 4.0/(1.+ x*x);

しかし、すでにお気づきのように、リダクションを使用する方が良い (そして一般的に高速) でしょう。

#pragma omp parallel for private(x) reduction(+:sum)
for (i=0; i<num_steps; i++)
{ 
    x = (i + .5)*step;
    sum = sum + 4.0/(1.+ x*x);  
}

( と書くこともできますsum += 4.0/(1.+ x*x);)

于 2012-12-25T22:52:53.723 に答える
3

に変更sum = sum + 4.0/( 1. + x*x )してみてくださいsum += 4.0/(1.+ x*x)、しかし私はこれもうまくいかないのではないかと心配しています。次のように作業を分割してみてください。

x = (i + .5)*step;
double xx = 4.0/(1.+ x*x);
#pragma omp atomic //this part contains error
sum += xx;

これは機能するはずですが、それがあなたのニーズに合っているかどうかはわかりません。

于 2012-12-24T01:26:08.247 に答える
2

交換 :

#pragma omp atomic

#pragma omp reduction(+:sum) または によって#pragma omp critical

しかし、sum + = Varがあるので、#pragmaompreductionがより良いオプションになると思います。

このようにしてください:

x = (i + .5)*step;
double z = 4.0/(1.+ x*x);
#pragma omp reduction(+:sum)
sum += z;
于 2012-12-24T04:24:23.080 に答える
0

おそらく#pragma、問題の実際の解決策以上のものについて要約する必要があります。

#pragma非標準コンパイラ固有のセットであり、ほとんどの場合、プラットフォーム/システム固有です。つまり、同じOSを搭載した異なるマシン、または単に異なるセットアップを備えたマシンで動作が異なる可能性があります。 -プロセッサ。

結果として、プラグマの問題は、選択したプラットフォームのコンパイラの公式ドキュメントを参照した場合にのみ解決できます。ここに2つのリンクがあります。

標準のC/C++#pragmaには存在しません。

于 2012-12-24T01:36:12.783 に答える