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 :

OpenMP ralentit au lieu de booster


Sujet :

Threads & Processus C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 25
    Par défaut OpenMP ralentit au lieu de booster
    Hello,

    J'ai fait un programme graphique que je souhaite optimiser. Je me suis donc intéresse à OpenMP (pour dire que j'y connais pas grand chose).

    Voila la partie du code que j'ai parallélisé:
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    void incrementation(Planete* A, int nmb)
    {
      int i;
      int l;
    float truc1;
    float truc2;
    float truc3;
    float distance;
     
     
    for(l=0;l<=nmb-1;l++)
    {
        truc1=0;
        truc2=0;
        truc3=0;
        distance=0;
     
    #pragma omp parallel for
        for(i=0;i<=nmb-1;i++)
        {
     
            if(!(i==l))
            {
                distance=(A[i].x_now-A[l].x_now)*(A[i].x_now-A[l].x_now)+(A[i].y_now-A[l].y_now)*(A[i].y_now-A[l].y_now)+(A[i].z_now-A[l].z_now)*(A[i].z_now-A[l].z_now);
     
                truc1=truc1+(G*A[i].masse*(A[i].x_now-A[l].x_now))/((distance+1)*sqrt(distance));
                truc2=truc2+(G*A[i].masse*(A[i].y_now-A[l].y_now))/((distance+1)*sqrt(distance));
                truc3=truc3+(G*A[i].masse*(A[i].z_now-A[l].z_now))/((distance+1)*sqrt(distance));
     
            }
     
        }
     
    A[l].x_after= truc1*PAS*PAS - A[l].x_past + 2*A[l].x_now;
    A[l].y_after= truc2*PAS*PAS - A[l].y_past + 2*A[l].y_now;
    A[l].z_after= truc3*PAS*PAS - A[l].z_past + 2*A[l].z_now;
     
    }
     
     
    #pragma omp parallel for
    for(l=0;l<=nmb-1;l++)
    { 
        A[l].x_past=A[l].x_now;
        A[l].y_past=A[l].y_now;
        A[l].z_past=A[l].z_now;
     
        A[l].x_now=A[l].x_after;
        A[l].y_now=A[l].y_after;
        A[l].z_now=A[l].z_after;
     
        A[l].x_after=0;
        A[l].y_after=0;
        A[l].z_after=0;
     
    }
     
    }
    Le problème c'est que au final à part avoir monté le pourcentage du processus utilisé de 25% à 96% (mon processeur a 4 coeur) la parallélisation n'a eut aucun effet sur la vitesse d’exécution du programme. Ça la même ralenti: j'ai une baisse de 3 ou 4 FPS par rapport au même code sans les : #pragma omp parallel for . De plus il y a aussi plus d'erreur de calcul( c'est moins stable).

    Donc ma question c'est est ce que OpenMP est vraiment utile ou est ce que c'est moi qui ne sais pas l'utilisé?

    Merci d'avance.

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonsoir

    Hum, difficile comme question. Allez, je tente une réponse... le problème vient peut être de toi ?

    Plus sérieusement, le problème avec OpenMP est que cela permet de faire du multithread facilement. Le problème avec ceux qui utilisent OpenMP est qu'ils croient que le multithreading est facile. En pratique, tout n'est pas parallélisable. Et rien n'est parallélisable n'importe comment.

    Faudra regarder en détail ton code, ton algo pour voir le problème, mais pas le temps ce soir

  3. #3
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Appeler une variable l ou O c'est assez troublant, la confusion avec 1 ou 0 est vite arrivée, et c'est pas facile à relire du coup :p

    Mais sinon le morceau de code
    truc1 += ...;
    truc2 += ...;
    truc3 += ...;
    me semble pas safe, si 2 threads accèdent en même temps à truc1 / truc2 / truc3, tu peux perdre la valeur d'un des threads.

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 25
    Par défaut
    Merci pour vos réponses.

    à gbdivers
    Je me doutai bien que ça venais de moi mais bon on a toujours espoir que l'on est sans reproche ^^
    Je vais essayer de trouver des cours pour mieux comprendre openMP alors

    à Iradrille
    Ça doit être pour ça que je trouve que c'est moins stable quand j'utilise le multi-threading :/
    Quelqu'un aurait une idée pour savoir comment éviter ce problème?

  5. #5
    Membre Expert Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Par défaut
    Salut,

    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
    for(l=0;l<=nmb-1;l++)
    {
        truc1=0;
        truc2=0;
        truc3=0;
        distance=0;
     
    #pragma omp parallel for
        for(i=0;i<=nmb-1;i++)
        {
     
            if(!(i==l))
            {
                distance=(A[i].x_now-A[l].x_now)*(A[i].x_now-A[l].x_now)+(A[i].y_now-A[l].y_now)*(A[i].y_now-A[l].y_now)+(A[i].z_now-A[l].z_now)*(A[i].z_now-A[l].z_now);
     
                truc1=truc1+(G*A[i].masse*(A[i].x_now-A[l].x_now))/((distance+1)*sqrt(distance));
                truc2=truc2+(G*A[i].masse*(A[i].y_now-A[l].y_now))/((distance+1)*sqrt(distance));
                truc3=truc3+(G*A[i].masse*(A[i].z_now-A[l].z_now))/((distance+1)*sqrt(distance));
     
            }
     
        }
     
    A[l].x_after= truc1*PAS*PAS - A[l].x_past + 2*A[l].x_now;
    A[l].y_after= truc2*PAS*PAS - A[l].y_past + 2*A[l].y_now;
    A[l].z_after= truc3*PAS*PAS - A[l].z_past + 2*A[l].z_now;
     
    }
    Dans ce code, la deuxième boucle ne peut pas être parallélisée… En effet comment veux-tu paralléliser quelque chose qui, à l'itération i, a besoin de données de l'itération i-1 ?

    Par contre la première boucle peut être parallélisée vu que chaque itération est indépendante l'une de l'autre (a première vue).

    À part ça, je n'aime pas trop tes notations de variable (truc notamment). Et l<=nmb-1 == i < nmb mais bon ça c'est plus du style qu'autre chose.

    J'ai retrouvé un petit lien sur la prog parallèle qui te donnera quelques bases (section Manycore) http://www.intel-software-academic-p...ses/index.html

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2012
    Messages : 25
    Par défaut
    à Trademark
    Tu veut dire mettre #pragma omp parallel for sur la boucle en l ?
    Comme cela?
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #pragma omp parallel for
    for(l=0;l<=nmb-1;l++)
    {
        float truc1=0;
        float truc2=0;
        float truc3=0;
        float distance=0;
     
        for(i=0;i<=nmb-1;i++)
        {
     
            if(!(i==l))
            {
                distance=(A[i].x_now-A[l].x_now)*(A[i].x_now-A[l].x_now)+(A[i].y_now-A[l].y_now)*(A[i].y_now-A[l].y_now)+(A[i].z_now-A[l].z_now)*(A[i].z_now-A[l].z_now);
     
                truc1=truc1+(G*A[i].masse*(A[i].x_now-A[l].x_now))/((distance+1)*sqrt(distance));
                truc2=truc2+(G*A[i].masse*(A[i].y_now-A[l].y_now))/((distance+1)*sqrt(distance));
                truc3=truc3+(G*A[i].masse*(A[i].z_now-A[l].z_now))/((distance+1)*sqrt(distance));
     
            }
     
        }
     
    A[l].x_after= truc1*PAS*PAS - A[l].x_past + 2*A[l].x_now;
    A[l].y_after= truc2*PAS*PAS - A[l].y_past + 2*A[l].y_now;
    A[l].z_after= truc3*PAS*PAS - A[l].z_past + 2*A[l].z_now;
     
    }
     
    for(l=0;l<=nmb-1;l++)
    { 
        A[l].x_past=A[l].x_now;
        A[l].y_past=A[l].y_now;
        A[l].z_past=A[l].z_now;
     
        A[l].x_now=A[l].x_after;
        A[l].y_now=A[l].y_after;
        A[l].z_now=A[l].z_after;
     
        A[l].x_after=0;
        A[l].y_after=0;
        A[l].z_after=0;
     
     
     printf("////////////////////////////////////  x %f y %f z %f \n",A[l].x_now,A[l].y_now,A[l].z_now);
     
    }
    J'ai essayer mais ça me donne quelque chose de très bizarre. Enfaite ça marche pendent un certain nombre d'itération (une cinquantaine) puis ça "explose".
    Voila ce que j'ai en réponse à une certaine itération (qui doit être la première où ça bug):
    //////////////////////////////////// x -1.#IND00 y -1.#IND00 z -1.#IND00
    //////////////////////////////////// x 1.173992 y 1.173772 z 0.830448
    //////////////////////////////////// x 0.000324 y 1.709239 z 0.855267
    //////////////////////////////////// x -0.991069 y 0.991448 z 0.697652
    //////////////////////////////////// x -1.532580 y 0.000020 z 0.767228
    //////////////////////////////////// x -1.191267 y -1.191673 z 0.843637
    //////////////////////////////////// x 0.000533 y -1.104066 z 0.553131
    //////////////////////////////////// x 1.137536 y -1.137083 z 0.804880
    //////////////////////////////////// x 1.794373 y 0.000017 z 0.897442
    //////////////////////////////////// x -0.005192 y -0.000273 z -0.010508
    J'ai jamais vu ces -1.#IND00 qu'est ce qu'ils signifient ? Erreur de calcul? Dépassement de capacité?

  7. #7
    Membre émérite
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 552
    Par défaut
    Citation Envoyé par rAyyy Voir le message
    Ça doit être pour ça que je trouve que c'est moins stable quand j'utilise le multi-threading :/
    Quelqu'un aurait une idée pour savoir comment éviter ce problème?
    Avant de faire du multi-threading avec une bibliothèque comme OpenMP, il faudrait peut-être que tu comprennes les difficultés liées aux threads.

    Là, tu fais des accès concurrent sur truc1, truc2, truc3 (reduction?) et tu as des accès concurrent sur distance (private?)

    Essaye de prendre un cours OpenMP et de faire le tour des instructions, elles sont la solution à des problèmes, tu connaîtras donc ces problèmes. Si tu t'arrêtes à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #pragma omp parallel for
    sans ce qui va derrière, tu ne t'en sortiras pas.

    J'aurais tendance à te conseiller de commencer par des choses simples pour te faire la main :
    * Somme de vecteur (pas de concurrence)
    * Min/max sur vecteur (accès concurrent sur le résultat)
    * Produit scalaire (réduction d'une somme)

    Tu auras moins de mal qu'en t'attaquant directement à des boucles imbriquées.

  8. #8
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Salut,

    pour paralléliser ton code avec OpenMP, il faut que tu apprennes les concepts d'OpenMP (Lapalisse n'aurait pas dit mieux) et notamment :
    1. les notions de données partagées et privées
    2. la notion de synchronisation
    3. la notion de réduction dans une boucle parallèle.
    Sans ça, tu n'y arriveras jamais. Avec ça, tu vas y arriver très facilement et très rapidement. Encore merci Lapalisse!

    Je t'invite à regarder le cours de l'IDRIS qui est très bien fait :
    http://www.idris.fr/data/cours/paral...choix_doc.html
    Si tu cherches les cours en C++ et que tu ne les trouves pas... c'est normal, ils sont bien en fortran! C'est très facile de les traduire en C++ et ce n'est pas cela qui importe. Je te conseille vivement de faire les TPs qui sont progressifs et introduisent bien les concepts.

    Pour te motiver un peu : ton code est réellement très simple à paralléliser, tu vas tomber sur la même problématique dans les TPs!

    @gbdivers : joli troll!

Discussions similaires

  1. [Designer 6i]: 6Bouton de navigation au lieu de 5
    Par patmaba dans le forum Designer
    Réponses: 7
    Dernier message: 30/07/2007, 07h49
  2. Pourquoi me conseille t'on le C au lieu de VB ?
    Par hicham000 dans le forum Langages de programmation
    Réponses: 16
    Dernier message: 11/06/2004, 19h38
  3. [BDD] renvoyer une chaine vide au lieu de null
    Par cmoulin dans le forum JDBC
    Réponses: 6
    Dernier message: 06/05/2004, 11h38
  4. Equivalent IN ms avec un ET au lieu du OU ds la lste
    Par Pompil dans le forum Requêtes
    Réponses: 4
    Dernier message: 04/03/2004, 21h20
  5. [TOMCAT] affichage arborescence au lieu d'éxécuter la servle
    Par lombra dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 13/08/2003, 13h30

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