2013-02-07 2 views
2

Je suis en train de tester la mise en vitesse pour un petit morceau de code comme suit:énorme ralentir en utilisant OpenMP

for(i=0;i<imgDim;i++) 
     { 
      X[0][i] = Z[i] - U1[i] * rhoinv; 
      X[1][i] = Z[i] - U2[i] * rhoinv; 
      X[2][i] = Z[i] - U3[i] * rhoinv; 
     } 

L'itération est d'environ 200 et imgDim est 1000000. La durée totale de ce morceau de code est d'environ 2 secondes. Et le code entier coûte environ 15 secondes. Mais après que je l'utilise OpenMP parallèle ce morceau de code comme:

omp_set_num_threads(max_threads); 
    #pragma omp parallel shared(X,Z,U1,U2,U3,imgDim,rhoinv) private(i) 
    { 
     #pragma omp for schedule(dynamic) 
     for(i=0;i<imgDim;i++) 
     { 
      X[0][i] = Z[i] - U1[i] * rhoinv; 
      X[1][i] = Z[i] - U2[i] * rhoinv; 
      X[2][i] = Z[i] - U3[i] * rhoinv; 
     } 
    } 

max_threads est 8. Seul ce petit morceau de besoin de code environ 11 secondes et l'utilisation de code entier environ 27 secondes. La chose la plus étrange est que le temps passe à 6 secondes si je mets max_threads à 1. Mais encore beaucoup plus longtemps que le code séquentiel.

Cela me coûte beaucoup de temps et je ne trouve pas le problème. Appréciez profondément si quelqu'un peut m'aider avec cela.

+0

Vous pourriez être en mémoire bound- -si vous êtes déjà en train de saturer votre bus mémoire, avoir plus de threads empilant sur les requêtes (tout en ayant leur propre surcharge, y compris l'accès mémoire pour le changement de contexte) serait inutile. – zebediah49

+0

Je suppose que le problème est que le travail par thread, étant seulement quelques multiplie et ajoute, est complètement submergé par le code pour créer/exécuter/détruire les threads parallèles. Essayez (pour i = 0; i }} pour assurer plus de travail par thread –

Répondre

3

schedule(dynamic) introduit un énorme temps d'exécution. Il ne devrait être utilisé que pour des boucles où chaque itération pourrait prendre un temps différent et l'équilibrage de la charge amélioré justifierait la surcharge. Pour les boucles régulières comme la vôtre, la planification dynamique est trop lourde car elle introduit une surcharge inutile, ce qui ralentit le calcul.

Modifier le type de programme à static:

#pragma omp parallel for schedule(static) 
for(i=0;i<imgDim;i++) 
{ 
    X[0][i] = Z[i] - U1[i] * rhoinv; 
    X[1][i] = Z[i] - U2[i] * rhoinv; 
    X[2][i] = Z[i] - U3[i] * rhoinv; 
} 

(Note: les variables déclarées dans les étendues extérieures sont partagées par défaut et la variable de contrôle de boucle parallèle est implicitement privé)

+0

Merci beaucoup. – mining