Question

Je suis assez nouveau pour OpenMP et je suis en train de commencer un fil individuel pour traiter chaque élément dans un tableau 2D.

Donc, essentiellement, ceci:

for (i = 0; i < dimension; i++) {
    for (int j = 0; j < dimension; j++) {
        a[i][j] = b[i][j] + c[i][j];

Ce que je fais est la suivante:

#pragma omp parallel for shared(a,b,c) private(i,j) reduction(+:diff) schedule(dynamic)
    for (i = 0; i < dimension; i++) {
        for (int j = 0; j < dimension; j++) {
            a[i][j] = b[i][j] + c[i][j];

Est-ce en fait démarrer un thread pour chaque élément 2D ou non? Comment puis-je tester cela? S'il est faux, ce qui est la bonne façon de le faire? Merci!

Note: Le code a été grandement simplifiée

Était-ce utile?

La solution

Seule la boucle extérieure est parallèle dans votre exemple de code. Vous pouvez tester en imprimant omp_get_thread_num() dans la boucle intérieure et vous verrez que, pour un i donné, le fil num est le même (bien sûr, ce test est démonstratif plutôt que définitive puisque différents essais donneront des résultats différents). Par exemple, avec:

#include <stdio.h>
#include <omp.h>
#define dimension 4

int main() {
    #pragma omp parallel for
    for (int i = 0; i < dimension; i++)
        for (int j = 0; j < dimension; j++)
            printf("i=%d, j=%d, thread = %d\n", i, j, omp_get_thread_num());
    }

Je reçois:

i=1, j=0, thread = 1
i=3, j=0, thread = 3
i=2, j=0, thread = 2
i=0, j=0, thread = 0
i=1, j=1, thread = 1
i=3, j=1, thread = 3
i=2, j=1, thread = 2
i=0, j=1, thread = 0
i=1, j=2, thread = 1
i=3, j=2, thread = 3
i=2, j=2, thread = 2
i=0, j=2, thread = 0
i=1, j=3, thread = 1
i=3, j=3, thread = 3
i=2, j=3, thread = 2
i=0, j=3, thread = 0

Pour le reste de votre code, vous voudrez peut-être mettre plus de détails dans une nouvelle question (il est difficile de dire à partir du petit échantillon), mais par exemple, vous ne pouvez pas mettre private(j) quand j est seulement déclaré plus tard. Il est automatiquement privé dans mon exemple ci-dessus. Je suppose que diff est une variable que nous ne pouvons pas voir dans l'échantillon. En outre, la i variable de boucle est automatiquement privée (de la spécifications - même dans la spécification 3.0)

  

La variable d'itération de boucle dans le   pour la boucle d'un ou de parallèle pour   construire est privé dans ce   construire.

Edit: Tous ce qui précède est correct pour le code que vous et je l'ai montré, mais vous pouvez être intéressé par ce qui suit. Pour OpenMP version 3.0 (disponible en exemple gcc version 4.4 , mais pas la version 4.3) il y a une clause de collapse où vous pouvez écrire le code que vous avez, mais avec #pragma omp parallel for collapse (2) de paralléliser aussi bien pour les boucles (voir la spécification ).

Modifier : OK, j'ai téléchargé gcc 4.5.0 et a couru le code ci-dessus, mais en utilisant collapse (2) pour obtenir la sortie suivante, montrant la boucle intérieure maintenant parallélisé:

i=0, j=0, thread = 0
i=0, j=2, thread = 1
i=1, j=0, thread = 2
i=2, j=0, thread = 4
i=0, j=1, thread = 0
i=1, j=2, thread = 3
i=3, j=0, thread = 6
i=2, j=2, thread = 5
i=3, j=2, thread = 7
i=0, j=3, thread = 1
i=1, j=1, thread = 2
i=2, j=1, thread = 4
i=1, j=3, thread = 3
i=3, j=1, thread = 6
i=2, j=3, thread = 5
i=3, j=3, thread = 7

Commentaires (recherche « ») sont Contournements aussi pertinentes pour contournements dans la version 2.5 si vous voulez paralléliser les deux boucles, mais la version 2.5 spec citée ci-dessus est tout à fait explicite (voir les exemples non conformes à la section A.35 ).

Autres conseils

Vous pouvez essayer d'utiliser imbriqué omp Fors parallèles (après appel omp_set_nested(1)), mais ils un non pris en charge toutes les implémentations OpenMP.

Je suppose que de faire une grille 2D et commencer à tous les fils sur la grille à partir unique pour (par exemple pour la grille de fil 4x4 fixe):

#pragma omp parallel for
for(k = 0; k < 16; k++)
{
    int i,j,i_min,j_min,i_max,j_max;
    i_min=(k/4) * (dimension/4);
    i_max=(k/4 + 1) * (dimension/4);
    j_min=(k%4) * (dimension/4);
    j_max=(k%4 + 1) * (dimension/4);

    for(i=i_min;i<i_max;i++)
      for(j=j_min;j<j_max;j++)
       f(i,j);

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top