2017-08-19 6 views
0

J'ai une version sérielle de BML et j'essaye d'en écrire une parallèle avec OpenMP. Fondamentalement, mon code fonctionne avec un main dans une boucle appelant deux fonctions pour les mouvements horizontaux et verticaux. Comme ceci:OpenMP dans le modèle BML de Biham-Middleton-Levine

for (s = 0; s < nmovss; s++) { 
     horizontal_movs(grid, N); 
     copy_sides(grid, N); 
     cur = 1-cur; 
     vertical_movs(grid, N); 
     copy_sides(grid, N); 
     cur = 1-cur; 
} 

cur est la grille actuelle. Ensuite, les fonctions horizontales et verticales sont similaires et ont une boucle imbriquée:

for(i = 1; i <= n; i++) { 
    for(j = 1; j <= n+1; j++) { 
     if(grid[cur][i][j-1] == LR && grid[cur][i][j] == EMPTY) { 
      grid[1-cur][i][j-1] = EMPTY; 
      grid[1-cur][i][j] = LR; 
     } 
     else { 
      grid[1-cur][i][j] = grid[cur][i][j]; 
     } 
    } 
} 

Le code produit une image de ppm à chaque étape, et petit morceau une certaine entrée de la version de série produire une sortie que l'on peut supposer bien. Mais en utilisant #pragma omp parallel for à l'intérieur des deux fonctions H et V, les résultats de fichier ppm dédoublées dans ces zones que le nombre de threads (par exemple 4):

final step

Je suppose que le problème est que chaque thread devrait faire les deux fonctionne en séquence avant termit parce que les movememnts sont strictement connectés. Je ne sais pas comment faire ça. Si je place le pragma à un niveau plus élevé comme avant la boucle principale, il n'y a pas d'accélération. Évidemment, le fichier ppm ne doit pas être découpé comme l'image.

+1

Juste une conjecture super sauvage car le niveau de détails que vous donnez est limité (montrez simplement le code parallélisé actuel, ce serait beaucoup plus utile), vous avez oublié de déclarer 'private (j)' dans votre '#pragma omp parallèle pour la ligne. Essayez simplement de l'ajouter et de voir ce qui se passe. – Gilles

+0

@Gilles 'default (none), shared et private' sont omis dans la question mais il y en a dans mon code. – Caramelleamare

Répondre

0

Goin'on J'ai essayé cette solution qui me donne un résultat identique au code de série, mais je ne excatly comprendre pourquoi

# pragma omp parallel num_threads(thread_count) default(none) \ 
    shared(grid, n, cur) private(i, j) 
    for(i = 1; i <= n+1; i++) { 
#  pragma omp for 
     for(j = 1; j <= n; j++) { 
      if(grid[cur][i-1][j] == TB && grid[cur][i][j] == EMPTY) { 
       grid[1-cur][i-1][j] = EMPTY; 
       grid[1-cur][i][j] = TB; 
      } 
      else { 
       grid[1-cur][i][j] = grid[cur][i][j]; 
      } 
     } 
    } 
} 

Par conséquent, si je viens d'utiliser un fil plus de cœurs disponibles (4), le temps d'exécution "explose" au lieu de rester à peine le même.