web-dev-qa-db-ja.com

OpenMPの並列forループ

私は非常に単純なforループを並列化しようとしていますが、これはopenMPを長い間使用する最初の試みです。実行時間に困惑しています。ここに私のコードがあります:

#include <vector>
#include <algorithm>

using namespace std;

int main () 
{
    int n=400000,  m=1000;  
    double x=0,y=0;
    double s=0;
    vector< double > shifts(n,0);


    #pragma omp parallel for 
    for (int j=0; j<n; j++) {

        double r=0.0;
        for (int i=0; i < m; i++){

            double Rand_g1 = cos(i/double(m));
            double Rand_g2 = sin(i/double(m));     

            x += Rand_g1;
            y += Rand_g2;
            r += sqrt(Rand_g1*Rand_g1 + Rand_g2*Rand_g2);
        }
        shifts[j] = r / m;
    }

    cout << *std::max_element( shifts.begin(), shifts.end() ) << endl;
}

私はそれをコンパイルします

g++ -O3 testMP.cc -o testMP  -I /opt/boost_1_48_0/include

つまり、「-fopenmp」はなく、これらのタイミングが得られます。

real    0m18.417s
user    0m18.357s
sys     0m0.004s

「-fopenmp」を使用すると、

g++ -O3 -fopenmp testMP.cc -o testMP  -I /opt/boost_1_48_0/include

時代のこれらの数字を取得します。

real    0m6.853s
user    0m52.007s
sys     0m0.008s

私には意味がありません。 8つのコアを使用すると、パフォーマンスがわずか3倍しか向上しないのはなぜですか?ループを正しくコーディングしていますか?

22
dsign

reductionおよびxにはOpenMPのy句を使用する必要があります。

#pragma omp parallel for reduction(+:x,y)
for (int j=0; j<n; j++) {

    double r=0.0;
    for (int i=0; i < m; i++){

        double Rand_g1 = cos(i/double(m));
        double Rand_g2 = sin(i/double(m));     

        x += Rand_g1;
        y += Rand_g2;
        r += sqrt(Rand_g1*Rand_g1 + Rand_g2*Rand_g2);
    }
    shifts[j] = r / m;
}

reductionを使用すると、各スレッドはxyにそれぞれの部分和を累積し、最終的にすべての部分値を合計して最終値を取得します。

Serial version:
25.05s user 0.01s system 99% cpu 25.059 total
OpenMP version w/ OMP_NUM_THREADS=16:
24.76s user 0.02s system 1590% cpu 1.559 total

参照-超線形高速化:)

25
Hristo Iliev

openMPを使用して単純なforループを並列化する方法を理解してみましょう

#pragma omp parallel
#pragma omp for
    for(i = 1; i < 13; i++)
    {
       c[i] = a[i] + b[i];
    }

3使用可能なスレッドがあると仮定すると、これが起こるでしょう

enter image description here

第一に

  • スレッドには、独立した反復セットが割り当てられます

そして最後に

  • スレッドは、ワークシェアリング構造の最後で待機する必要があります
13