2010-07-20 3 views
1

Je ne comprends pas, où est-ce que je me trompe? Si compilé sans support openmp, le code fonctionne correctement. Mais avec les variables openmp semblent obtenir une mauvaise visibilité.Visibilité de la variable OpenMP C++ dans les tâches parallèles

J'avais l'intention suivante. Chaque thread a son propre max_private dans lequel il trouve le maximum local. Ensuite, un maximum global est trouvé dans une section critique.

#include <iostream> 
#include <vector> 

typedef std::vector<long> Vector; 

long max(const Vector& a, const Vector& b) 
{ 
    long max = 0; 
    #pragma omp parallel 
    { 
     long max_private = 0; 

     #pragma omp single 
     { 
      for ( Vector::const_iterator a_it = a.begin(); 
        a_it != a.end(); 
        ++a_it) 
      { 
       #pragma omp task 
       { 
        for ( Vector::const_iterator b_it = b.begin(); 
          b_it != b.end(); 
          ++b_it) 
        { 
         if (*a_it + *b_it > max_private) { 
          max_private = *a_it + *b_it; 
         } 
        } 
       } 
      } 
     } 

     #pragma omp critical 
     { 
      std::cout << max_private << std::endl; 
      if (max_private > max) { 
       max = max_private; 
      } 
     } 
    } 
    return max; 
} 

int main(int argc, char* argv[]) 
{ 
    Vector a(100000); 
    Vector b(10000); 
    for (long i = 0; i < a.size(); ++i) { 
     a[i] = i; 
    } 
    for (long i = 0; i < b.size(); ++i) { 
     b[i] = i * i; 
    } 

    std::cout << max(a, b) << std::endl; 

    return 0; 
} 

Je ne veux pas utiliser parallèle, car celui-ci, je vais utiliser des structures de données qui ne prennent pas en charge itérateurs d'accès aléatoire.

J'ai utilisé le compilateur g ++ - 4.4.

Répondre

0

Je pense que vous avez besoin de quelques attributs sur les variables. Par défaut, toutes les variables sont partagées, et comme vous voulez que max_private soit par thread, vous pouvez ajouter une clause private à sa déclaration (cela pourrait aller un peu plus vite).

Pour max, vous avez besoin de le mettre à l'intérieur du bloc OMP, et marquer avec « partagée » si elle ne fonctionne toujours pas correctement (bien qu'il devrait être ok comme vous l'avez) Alors

, je pense que vous voulez #pragma omp parallel private(max_private) et mettre les deux variables en dehors du bloc omp principal.

+0

J'ai essayé votre suggestion du troisième paragraphe, mais cela ne fonctionne pas pour moi. Voici le diff pour être sûr que j'ai bien compris: 9c9,10 <#pragma omp parallèle --- > long max_private = 0; > #pragma omp parallèle privé (max_privé) 11,12c12 max_private = 0; – tswr

+0

Il semble que le max_private de la tâche ne soit jamais copié sur max_private qui est local pour chaque thread – tswr

+0

hmm. Je ne sais pas - mais j'essaierais d'ajouter 'private (max_private)' à la directive '#pragma omp task'. – gbjbaanb

0

Ce dont vous avez besoin est une réduction de openmp pour trouver le maximum. Il est availaible à OpenMP 3.0

Est-ce que la réduction du pour

long max(const Vector& a, const Vector& b) 
{ 
    long max_val = 0; // <- change the name for clarity 
    #pragma omp parallel reduction(max : max_val) 
    { 
     [...] 
     #pragma omp critical 
     { 
     std::cout << max_private << std::endl; 
     if (max_private > max_val) { 
      max_val = max_private; 
     } 
     } 
    } 
    return max_val; 
} 

MAX_VAL est privé dans chaque fil et à la fin de la boucle la réduction se produit et revenir le maximum de chaque fils de open_mp.

Questions connexes