2012-03-28 2 views
0

私はこのコードを実行すると答えとして2542199.979500が得られます。ただし、正解は1271099.989750です。誰かがエラーがどこにあるのか教えていただけますか?正しい合計が得られない - openmp

これはバグが含まれているコードです:

さらに
#include <omp.h> 
#define N 1000 

main() 
{ 
    int i, nthreads; 
    int chunk = 10; 
    float a[N], b[N], c[N], d[N]; 
    double result; 
    #pragma omp parallel 
    { 
     nthreads = omp_get_num_threads(); 
     printf("no of threads %d", nthreads);  
     #pragma for shared(a,b,c,d,result) private(i) schedule(static,chunk) 
     for (i=0; i < N; i++){ 
      a[i] = i * 1.5; 
      b[i] = i + 22.35; 
     } 
     #pragma for shared(a,b,c,d,result) private(i) schedule(static,chunk) 
     for(i=0; i < N; i++){ 
      result = result + (a[i]+b[i]); 
     } 
    } 
    printf("value is %f", result); 
} 

スレッドの数が3であるとき、私は結果が使用されるスレッドの数に依存 3813299.969250

を取得します。これはopenmpのバグでしょうか、間違っていますか?最終的なプラグマの

+0

あなたは私達にあなたのコードの意図を伝えることはできますか?私はあなたが期待しているアウトプットをなぜ期待しているのですか? –

+2

私はopenmpなしで同じことをして、得た1271099.989750 – user602774

+0

今、どのようなものが正しいと思いますか?私の質問はあなたのコードは何ですか? "私のコードはN個の数字を並べ替える"、 "私のコードは1個からN個まで数字を追加する"のようなものです。同様に、あなたのコードは何をしますか? –

答えて

1

私は、少なくとも次の二つの変更... resultの宣言の

を示唆...

// result should be initialized 
double result = 0; 

...

// specify the "reduction" 
#pragma omp parallel for reduction(+:result) 

指定せず"reduction"の場合、resultへの合計はresultが各スレッドで独立して変更されるため無効です。その結果、rac状態。

は、コメントをインラインでご覧くださいhttp://en.wikipedia.org/wiki/OpenMP#Reduction


#include <stdio.h> 
#include <omp.h> 
#define N 1000 

int main() 
{ 

int i, nthreads; 
int chunk = 10; 
float a[N], b[N], c[N], d[N]; 
double result=0; 

#pragma omp parallel 
nthreads = omp_get_num_threads(); 
printf("no of threads %d\n", nthreads); 

#pragma omp parallel for 
for (i=0; i < N; i++){ 
    a[i] = i * 1.5; 
    b[i] = i + 22.35; 
} 

#pragma omp parallel for reduction(+:result) 
for(i=0; i < N; i++){ 
result = result + (a[i]+b[i]); 
} 

printf("value is %f", result); 

return 0; 
} 
+0

もう1つ:最初の '#pragma omp parallel'を取り除きたくなるでしょう。私はそれがあなたがしたいことをしないと思う。 – nobar

+0

私はあなたが言ったすべてのことをしましたが、それでも私に間違った答えを与えます:( – user602774

1

を参照してください。 cc -fopenmp -std=gnu99 openmp.cを用い

// openmp.c 
#include <stdio.h> 
#include <omp.h> 

#define N 1000 

// main should return a int 
int main(){ 
    int i, nthreads; 
    float a[N], b[N]; 
    // give result a initial value ! 
    double result = 0; 

#pragma omp parallel 
{ 
    nthreads = omp_get_num_threads(); 
    // just print numthreads ONCE 
#pragma omp single 
    printf("no. of threads %d\n", nthreads); 

#pragma omp for 
    for (int i = 0; i < N; i++) { 
     a[i] = i *1.5; 
     b[i] = i + 22.35; 
    } 

#pragma omp for 
    for (int i = 0; i < N; i++) { 
     double sum = a[i] + b[i]; 
// atomic operation needed ! 
#pragma omp atomic 
     result += sum; 
    } 

#pragma omp single 
    printf("result = %f\n", result); 
} 
    return 0; 
} 

コンパイル、出力は:OpenMPの一

no. of threads 4 
result = 1271099.989750 
+0

'#pragma omp single'の行は本当に必要ですか?それらの行はシングルスレッドのコンテキストにはありませんか? '' omp 'を含まないためエラーです – nobar

+0

'#pragma omp for'は実際には複数のスレッドを使用していない可能性がありますので、' #pragma omp parallel for'で試してみてください – nobar

+0

ニックピック、 – nobar

0

一方が可能であるために十分なこの場合には、並列領域を最小限に抑えるように試みるべきです。ここには単純なC++バージョンがあります。

#include <iostream> 
#include <iomanip> 
#include <omp.h> 

const int N=1000; 

int main() 
{ 
    const double A = 22.35; 
    const double B = 1.5; 

    double a[N], b[N], c[N], d[N]; 
    double result=0; 

#pragma omp parallel 
    { // begin parallel region 
#pragma omp master 
    std::cout << "no of threads: " << omp_get_num_threads() << std::endl; 

    // this loop and the following could be merged and the arrays avoided. 
#pragma omp for 
    for(int i=0; i<N; ++i) { 
     a[i] = i * B; 
     b[i] = i + A; 
    } 
#pragma omp for reduction(+:result) 
    for(int i=0; i<N; ++i) 
     result += a[i]+b[i]; 
    } // end parallel region 

    double answer = N*(A+0.5*(B+1)*(N-1)); 

    std::cout << "computed result = " << std::setprecision(16) << result 
      << '\n' 
      << "correct answer = " << std::setprecision(16) << answer 
      << std::endl; 

    return 0; 
} 

私がする(Mac OS X 10.6.8上でGCC 4.6.2を使用して)取得:

no of threads: 2 
computed result = 1271099.999999993 
correct answer = 1271100 
関連する問題