Parallèle pour la boucle dans openmp

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

#include  #include  using namespace std; int main () { int n=400000, m=1000; double x=0,y=0; double s=0; vector 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 comstack 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 les époques:

 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-elle aboutir qu’à une multiplication par trois des performances? Est-ce que je code correctement la boucle?

Vous devriez utiliser la clause de reduction OpenMP pour x et y :

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

Avec la reduction chaque thread accumule sa propre sum partielle en 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 super linéaire 🙂

Essayons de comprendre comment paralléliser une boucle simple avec OpenMP

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

supposons que nous avons 3 discussions disponibles, c'est ce qui va arriver

entrez la description de l'image ici

d'abord

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

et enfin

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

Ce que vous pouvez réaliser au mieux (!) Est une accélération linéaire. Maintenant, je ne me souviens plus qui est avec les heures de linux, mais je vous conseillerais d’utiliser time.h ou (en c ++ 11) “chrono” et de mesurer le temps d’exécution directement à partir du programme. Il est préférable d’intégrer le code complet dans une boucle, de l’exécuter 10 fois et d’obtenir une exécution approximative du prog.

De plus, vous avez un problème avec x, y – qui n’adhère pas au paradigme de la localité de données dans la programmation parallèle.