2009-11-10 7 views
6

I ont deux fonctions, do_step_one(i) et do_step_two(i), pour i de 0 à N-1.Comment créer un `omp parallèle for` avec synchronisation (` barrier`) de tous les fils dans le milieu avec OpenMP

Actuellement, j'ai ce code (séquentiel):

for(unsigned int i=0; i<N; i++) { 
    do_step_one(i); 
} 

for(unsigned int i=0; i<N; i++) { 
    do_step_two(i); 
} 

Chaque appel de do_step_one() et do_step2() peut être fait dans l'ordre et en parallèle, mais toute do_step_two() a besoin de la fin de tous les do_step_one() pour commencer (il utilise do_step_one() résultats).

J'ai essayé les éléments suivants:

#omp parallel for 
for(unsigned int i=0; i<N; i++) { 
    do_step_one(i); 

#omp barrier 

    do_step_two(i); 
} 

Mais gcc se plaint

convolve_slices.c: 21: avertissement: zone barrière ne peut pas être étroitement imbriquées à l'intérieur du partage du travail, critique, ordonné, master ou zone de tâche explicite.

Qu'est-ce que je ne comprends pas? Comment résoudre ce problème?

+0

Votre syntaxe OpenMP semble erroné - pour les appels que vous semblez être manquant le '# pragma' - l'avez-vous omis ou n'est-ce pas là? –

+1

Je l'omets, désolé, mais dans le code réel, ils sont ici. –

Répondre

4

Un problème que je vois avec ce code, est que le code ne respecte pas la spécification :)

Si vous avez besoin tous do_step_one() est à la fin, vous aurez besoin de quelque chose comme ce qui suit:

#pragma omp parallel for 
for(unsigned int i=0; i<N; i++){ 
    do_step_one(i); 
} 

#pragma omp parallel for 
for(unsigned int i=0; i<N; i++){ 
    do_step_two(i); 
} 

Le résultat de ceci serait un parallélisme du premier pour, puis un parallélisme du second pour.

+0

J'ai oublié la plupart de mon travail en OMP - cette méthode maintient-elle les threads ou a-t-elle besoin de les recréer pour le second 'parallel for'? –

+1

Je ne suis pas sûr de ça. C'est une question de mise en œuvre intérieure. Formellement, il peut créer les threads à nouveau pour la deuxième boucle, mais je pense qu'ils pourraient avoir des optimisations pour éviter cela. – Anna

+0

Oh, je pense que je comprends maintenant où vous en arrivez - le premier pour devra finir pour que le second commence, puisque le parallélisme est fait par bloc. Pour être certain (il n'aura probablement aucun effet), il est possible de placer une barrière entre les deux boucles. – Anna

11

Juste une note de côté, si vous voulez vous assurer que les fils ne sont pas recréées, séparer la déclaration de parallèle et la déclaration de pour:

#pragma omp parallel 
{ 
    #pragma omp for 
    for(unsigned int i=0; i<N; i++){ 
    do_step_one(i); 
    } 
    //implicit barrier here 
    #pragma omp for 
    for(unsigned int i=0; i<N; i++){ 
    do_step_two(i); 
    } 
} 
Questions connexes