2017-05-16 6 views
0

J'ai le code suivant que je voudrais écrire dans openmp.Traduction du code séquentiel dans la construction parallèle openMP

Mon code ressemble abstraitement comme ce qui suit

Je commence d'abord avec la division N=100 itérations à parts égales entre p=10 morceaux et je stocke les itérations allouées pour chaque pièce dans un vecteur

Nvec[1]={0,1,..,9} 
Nvec[2]={10,11,..,19} 
Nvec[p]={N-9,..,N} 

je boucle sur la itérations

for(k=0;k<p;k++){\\loop on each piece of Nvec 
    for(j=0;j<2;j++){\\here is a nested loop 
     for(i=Nvec[k][0];i<Nvec[k][p];i++){ 
      \\then I loop between the first and 
      \\last value of the array corresponding to piece k 
    } 
} 

Maintenant, comme vous pouvez voir le code est séquentiel avec un total de 2*100=200 iterations, j'ai voulu le paralléliser en utilisant OpenMp avec la condition absolue de garder l'ordre des itérations!

J'ai essayé ce paramètre ne tient pas la

suivante
#pragma omp parallel for schedule(static) collapse(2) 
{ 
for(j=0;j<2;j++){ 
    for(i=0;i<n;i++){ 
     \\loop code here 
    } 
} 
} 

l'ordre des itérations comme dans la version séquentielle. Dans la version séquentielle, chaque segment est traité entièrement avec j=0, puis entièrement avec j=1.

Dans ma version openMP, chaque thread prend un morceau d'itérations et le traite entièrement avec j=0. Dans un certain sens, tous les threads traitent les cas j=0 ou j=1. Chaque travailleur avec p=10 traite 200/10=20 iterations, le problème est toutes les itérations sont j=0 or j=1.

Comment puis-je faire en sorte que chaque thread obtenir un morceau d'itérations, exécute le code de boucle avec j=0 sur tous les itérations, puis j=1 sur le même morceau d'itérations?

EDIT

ce que je veux exactement pour chaque morceau de 20 itérations

worker 1 
j:0 
i:1--->10 
j:1 
i:1--->10 
worker p 
j:0 
i:90--->99 
j:1 
i:90--->99 

le code openMP ci-dessus ne

worker 1 
j:0 
i:1--->20 
worker p 
j:1 
i:80--->99 
+3

Ne pouvez-vous pas modifier l'ordre des boucles, c'est-à-dire faire la boucle externe pour 'i' et la boucle interne pour' j'? –

+0

oui, dans ce cas, chaque itération 'i' reçoit successivement' j = 0' et 'j = 1'. Je suis intéressé à avoir 'j = 0' pour toutes les itérations dans le morceau ** puis **' j = 1' sur les mêmes itérations.La commande est importante pour la vitesse par rapport à mon problème. – Marouen

Répondre

1

Il est en fait simple - juste faire la j extérieure -loop non -partage:

#pragma omp parallel 
for (int j = 0; j < 2; j++) { 
    #pragma omp for schedule(static) 
    for (int i = 0; i < 10; i++) { 
     ... 
    } 
} 

Si vous utilisez la planification static, OpenMP garantit que chaque travailleur pourra gérer la même plage de i s pour j=0 et j=1.

Remarque: Le déplacement de la construction parallel vers la boucle externe est simplement une optimisation pour éviter le surdébit de gestion des threads. Le code fonctionne de la même manière si vous placez un parallel for entre les deux boucles.

+0

Super, merci! est-il possible de garantir la commande dans un planning dynamique? – Marouen

+0

@Marouen Que voulez-vous dire par "garantir la commande". Bien sûr, un calendrier dynamique ne garantit pas la distribution égale des indices pour les boucles successives. Cela irait à l'encontre de tout le but. – Zulan

+1

La planification par défaut dépend de l'implémentation, pas de 'static'. –