web-dev-qa-db-fra.com

Parallèle pour boucle dans openmp

J'essaie de paralléliser une boucle for très simple, mais c'est ma première tentative d'utiliser openMP depuis longtemps. Je suis déconcerté par les temps d'exécution. Voici mon code:

#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;
}

Je le compile avec

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

c'est-à-dire, pas de "-fopenmp", et j'obtiens ces timings:

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

quand j'utilise "-fopenmp",

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

Je reçois ces chiffres pour l'époque:

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

ce qui n'a pas de sens pour moi. Comment l'utilisation de huit cœurs ne peut entraîner qu'une augmentation de 3 fois des performances? Suis-je en train de coder la boucle correctement?

22
dsign

Vous devez utiliser la clause OpenMP reduction pour x et 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;
}

Avec reduction chaque thread accumule sa propre somme partielle dans x et y et à la fin toutes les valeurs partielles sont additionnées afin d'obtenir les valeurs finales.

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

Voir - accélération superlinéaire :)

25
Hristo Iliev

essayons de comprendre comment paralléliser une boucle simple en utilisant OpenMP

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

supposons que nous avons 3 threads disponibles, c'est ce qui va se passer

enter image description here

d'abord

  • Les threads se voient attribuer un ensemble indépendant d'itérations

et enfin

  • Les threads doivent attendre à la fin de la construction de travail partagé
13