IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Threads & Processus C++ Discussion :

Pb OpenMP avec fonction + boucles


Sujet :

Threads & Processus C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2007
    Messages : 15
    Par défaut Pb OpenMP avec fonction + boucles
    Bonjour,

    Je viens vers vous, afin d'avoir des conseilles sur OpenMP.
    Dans mon code C, je parallélise une partie (voir partie très simplifiée ci-dessous):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    int k=0;
    #pragma omp parallel for
     
    for (int i = 0 ; i < 10  ; ++i)
        for (int l = 0 ; l < 10  ; ++l) {
     
            if (_p[k]==0)         funct_1(i,k);
            else if (_p[k]==1)   funct_2(i,k);
     
            ++k;
        }
    Il se trouve qu'en rajoutant la ligne (#pragma omp parallel for), mes résultats sont complètement faux. Je ne maîtrise pas encore toutes les les fonctionnalités d'OpenMP.
    Dois je rajouter d'autres mots-clés ?
    A quoi cela sert de privatiser ou de les partager des variables entre les threads ?
    J'ai lu la documentation plusieurs fois, mais je ne comprends pas l'intérêt. Pouvez-vous me l'expliquer ?

    Je vous remercie pour vos éventuelles réponses
    Syens

  2. #2
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    que font tes fonctions ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2007
    Messages : 15
    Par défaut
    Bonsoir,

    Mes fonctions réalisent des opérations très basiques, en voici un exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    static inline void funct_1 (int i, int k) {
     
        dn = x(i) - position_mur_x - rayon(i);
     
        F(k) = Kn1 * dn;
     
        f_part(i) += F(k);
        MurY0.f -= F(k);
    }
    Merci
    Syens

  4. #4
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2010
    Messages : 26
    Par défaut
    Hey,

    Tu as des accés concurrents sur la variable f_part(i) ce qui peut-etre la source de tes résultats faux. Il faut spécifier que cette variable est shared.
    F(k) peut probablement être accédé par plusieurs threads en meme temps.

    J'écrirais plutot ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
     
    #pragma omp parallel for private(i,k) shared(f_part,F)
     
    for (int i = 0 ; i < 10 ; ++i)
    for (int k= 0 ; k< 10 ; ++k) {
     
    if (_p[k]==0)
    {
    dn = x(i) - position_mur_x - rayon(i);
     
    F(k) = Kn1 * dn;
     
    f_part(i) += F(k);
    MurY0.f -= F(k);
    }
    else if (_p[k]==1){
    dn = x(i) - position_mur_x - rayon(i);
     
    F(k) = Kn1 * dn;
     
    f_part(i) += F(k);
    MurY0.f -= F(k);
    }
     
     
    }

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2007
    Messages : 15
    Par défaut
    Merci beaucoup de ta réponse, elle m'a donnée pas mal de pistes.
    Il faut savoir que les variables globales (f_part,F) ne peuvent pas être facilement partagées. Donc j'ai choisi l'option default(shared).

    Ensuite mon code tourne parfaitement qd je parallélise uniquement la 2ième boucle et que je fais un omp critical pour mes fonctions:


    !! Attention !! j'ai posté mes vraies boucles pour plus de compréhension du code. J'ai ajouté les variables: nbreVoisin et voisin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int k=0;
     
    for (int i = 0 ; i < 10  ; ++i)
    #pragma omp parallel for default(shared)
        for (int l = 0 ; l < nbreVoisin[i]  ; ++l) {
    #pragma omp critical
    {    
            if (_p[k]==0)         funct_1(i,voisin[k]);
            else if (_p[k]==1)   funct_2(i,voisin[k]);
     
            ++k;
    }
        }
    J'aimerais bien savoir pourquoi je ne peux pas appliquer la parallélisation sur la première boucle. Si quelqu'un a une suggestion à faire, je suis preneur.
    Merci
    Syens

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2007
    Messages : 15
    Par défaut
    Bonjour,

    En utilisant le #pragma omp critical, la parallélisation du code n'est pas optimale. Comment puis-je partager des variables globales qui sont au sein des fonctions (e.g. la variable f_part) ?

    Merci
    JF

  7. #7
    Membre confirmé
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Avril 2010
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Avril 2010
    Messages : 26
    Par défaut
    Tu as trop de variables partagées. Il faut repenser ton code
    Ca explique pourquoi 1 tu ne peux pas paralléliser la première boucle et obtenir des résultats correctes.

    Pour les variables globales partagées normalement ca doit marcher, mais je ne suis pas sur (j'utilise jamais de variable globale).

    Citation Envoyé par Syens Voir le message
    J'aimerais bien savoir pourquoi je ne peux pas appliquer la parallélisation sur la première boucle. Si quelqu'un a une suggestion à faire, je suis preneur.


    Merci
    Syens

    Après réflexion, peux tu expliquer que fais ton code ? Ca permettra d'y voir plus clair et de proposer une solution adaptée.

    Pour les perfs avec ton code actuel, voilà une voie plus saine pour les boucles internes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
     
    int k=0;
    int tmp=0;
     
    #pragma omp parallel 
    {
     
       for (int i = 0 ; i < 10  ; ++i)
       {
    #pragma omp for private(i,l,k) reduction(+:tmp)
          for (int l = 0 ; l < nbreVoisin[i]  ; ++l)
          {   
            if (_p[k+l]==0)        tmp = tmp + funct_1(i,voisin[k+l]);
            else if (_p[k+l]==1)   tmp = tmp + funct_2(i,voisin[k+l]);
     
           }
            f_part(i)+=tmp;
            k+=nbreVoisin[i]-1;
         }
       }
    }
     
     
     
    int funct_1 (int i, int k) {
     
    dn = x(i) - position_mur_x - rayon(i);
     
    F(k) = Kn1 * dn;
     
    MurY0.f -= F(k);
    return F(k);
    }
    Déclarer une section parallel permet d'éviter de recréer les threads.
    Regarde si ce code fonctionne, ca devrait améliorer certaines choses.

    La variable k n'est plus partagée et est devenu virtuellement privée pour chaque thread. Tu fais un count global donc autant ajouter ca à la fin du parallélisme. J'ai modifié également ta fonction de manière à ce que la variable f_part ne soit plus partagée. J'utilise la variable tmp sur laquelle est fait une sommation parallel (reduction) et le résultat est ensuite mit dans f_part(i). De toute f_part(i) n'est pas accèder en parallèle. Je crois ne pas avoir foiré. f_part(i) n'était pas utilisé autre part dans ta fonction.

    ok, donnes nous ton feedback la dessus.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 31
    Par défaut
    Salut, en lisant vos différentes contributions au sujet de la parallélisation sur le forum, et en procédant moi-même à des tests d'implémentation, je me dis finalement que j'ai encore bien de la difficulté à reconnaître d’un coup d’œil les variables qui vont être "accédées" par plusieurs threads. Pour l'instant, je ne vois que les variables globales. Quels-sont vos conseils pour faire une analyse des variables partagées du code? Et dans OMP, à quoi cela va servir au compilo de savoir qu’une variable est « shared » ? Quelle va être la différence d’avec la directive « reduction » que l’on place dans certaines boucles for ? Merci de vos réponses.

Discussions similaires

  1. Fonction boucle avec condition
    Par gaetanos dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 21/05/2015, 15h12
  2. [Toutes versions] Modifier la formule d'une colonne en fonction d'une autre avec une boucle
    Par captaincss dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 01/07/2014, 18h20
  3. probleme de boucle avec fonction et appel
    Par Invité dans le forum Langage
    Réponses: 2
    Dernier message: 26/05/2011, 15h37
  4. Boucle avec fonction
    Par croset dans le forum R
    Réponses: 4
    Dernier message: 14/06/2010, 20h59
  5. fonction avec la boucle while
    Par hanou88 dans le forum C
    Réponses: 4
    Dernier message: 04/12/2009, 03h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo