2016-10-21 6 views
-1

OpenMPを使用して次のコードを並列化しようとしていますが、成功しません。 私はいくつかの例をインターネットで検索しましたが、何度もプログラムを実行した後で同じ答えを私に与えるものはありません。OpenMP Paralellize Pi program

int main (int argc, char **argv){ 

//Variables 
int i=0, aux=0; 
double step = 1.0/100000.0; 
double x=0.0, 
     pi=0.0, 
     sum = 0.0; 

#pragma omp parallel shared(sum,i) private(x) 
{ 
    x = 0.0; 
    sum = 0.0; 

    #pragma omp for 
    for (i=0; i<num_steps; ++i) { 
     x = (i-0.5)*step; 

     #pragma omp critical 
     sum += 4.0/(1.0+x*x); 

    } 
} 

/* All threads join master thread and terminate */ 
pi= step*sum; 
printf("PI value = %f\n", pi); 

}

は、事前にありがとう:

#include <stdio.h> 
#include <omp.h> 
#define NUM_THREADS 2 

long num_steps = 100000; 
double step = 1.0/100000.0; 

int main() { 
int i; 
double x, pi, sum = 0.0; 
for(i = 0; i < num_steps; ++i) { 
x = (i-0.5)*step; 
sum += 4.0/(1.0+x*x); 
} 
pi = step*sum; 
printf("PI value = %f\n", pi); 

}

これは私がこれまで持っているソリューションです。

答えて

-1

答えは:

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

long num_steps = 100000; 
double step = 1.0/100000.0; 

int main() { 
int i; 
double x, pi, sum = 0.0; 

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

} 


pi = step*sum; 
printf("PI value = %f\n", pi); 

}

-1

あなたの主な問題は、あなたがを共有iとして、あなたのループインデックスを宣言することです。これにより、すべてのスレッドが評価で同じiを使用するようになります。 OpenMPで実際にやりたいことは、iの全範囲を端数で分割し、各端数に異なる端数を割り当てることです。したがって、iprivateと割り当ててください。

パラレル領域でxsumを再初期化する必要はありません。いくつかの無関係なコンパイルエラーを修正した後、あなたのコードは次のようになります。あなたがsumを更新するたびにあなたが全体の並列領域を一時停止するので

#include<stdio.h> 
#include <omp.h> 
#define NUM_THREADS 2 

int main (int argc, char **argv){ 

//Variables 
int i=0, aux=0; 
double step = 1.0/100000.0; 
long num_steps = 100000; 
double x=0.0, 
     pi=0.0, 
     sum = 0.0; 

#pragma omp parallel shared(sum) private(i,x) 
{ 
    #pragma omp for 
    for (i=0; i<num_steps; ++i) { 
     x = (i-0.5)*step; 

     #pragma omp critical 
     sum += 4.0/(1.0+x*x); 
    } 
} 

/* All threads join master thread and terminate */ 
pi= step*sum; 
printf("PI value = %f\n", pi); 

} 

が、これはパフォーマンスの面ではるかに完璧からであることに注意してください。より速くあなたのコードを作るための最初のステップは、代わりにreductionとしてcritical一部を除去し、sumを宣言することである:

#pragma omp parallel private(i,x) 
{ 
    #pragma omp for reduction(+:sum) 
    for (i=0; i<num_steps; ++i) { 
     x = (i-0.5)*step; 

     sum += 4.0/(1.0+x*x); 
    } 
} 
+0

このコードは私にそれを数回実行した後に同じ結果を与えるものではありません。 – Alessandroempire

+1

'reduce'と' nowait'を組み合わせることは競合条件につながる可能性があるため危険です。特に、 'reduction'節が並列構造に適用され、並列領域に適用されない場合、危険です。それに加えて、そのような場合には 'nowait'は役に立たない。 –

+0

@Alessandroempireそれは奇妙なことですが、どちらのコードでもコンピュータ上で合った結果が得られます(共有iでは間違っていました)、最初のものはあなたの答えと同じように見えます。あなたのコードで一貫した結果が得られますか? – MakisH