|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||
|
Invité de passage
![]() Étudiant Inscription : octobre 2012 Messages : 25 ![]() |
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 :
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. |
||
|
|
00
|
|
|
#2 |
![]() ![]() ![]() Guillaume BelzBiochimiste Inscription : novembre 2008 Messages : 5 314 ![]() |
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
__________________
Vous souhaitez rejoindre l'équipe de bénévoles qui fait vivre Developpez (traduction, rédaction, modération) ? Contactez moi par MP. Ma page personnelle avec la liste de mes articles - Mon blog sur le C++, Qt et les GPU. Je suis régulièrement sur le chat pour les questions C++/Qt. Apprendre Qt 5 : vidéos d'installation (YouTube), extraites du livre Créer des applications avec Qt 5. |
|
10
|
|
|
#3 |
|
Membre éprouvé
![]() Étudiant Inscription : juin 2012 Messages : 264 ![]() |
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. |
|
|
20
|
|
|
#4 |
|
Invité de passage
![]() Étudiant Inscription : octobre 2012 Messages : 25 ![]() |
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? |
|
|
00
|
|
|
#5 | ||
|
Membre émérite
![]() Inscription : février 2009 Messages : 563 ![]() |
Salut,
Code :
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 |
||
|
|
10
|
|
|
#6 | |||
|
Invité de passage
![]() Étudiant Inscription : octobre 2012 Messages : 25 ![]() |
à Trademark
Tu veut dire mettre #pragma omp parallel for sur la boucle en l ? Comme cela? Code :
Voila ce que j'ai en réponse à une certaine itération (qui doit être la première où ça bug): Citation:
|
|||
|
|
00
|
|
|
#7 | |
|
Membre expérimenté
![]() Ingénieur développement logiciels Inscription : mars 2009 Messages : 331 ![]() |
Citation:
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 à 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. |
|
|
|
30
|
|
|
#8 |
|
Membre Expert
![]() Chercheur Inscription : mars 2010 Messages : 1 143 ![]() |
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! |
|
|
10
|
|
|
#9 |
|
Expert Confirmé Sénior
![]() |
Ce code fait ce qu'on appelle une réduction puisqu'il fait une somme cumulative en boucle.
Je sais qu'il y a un pragma pour OpenMP qui gère ça.
__________________
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant. "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?" Apparently everyone. -- Raymond Chen. Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen. |
|
|
10
|
|
|
#10 |
|
Invité de passage
![]() Étudiant Inscription : octobre 2012 Messages : 25 ![]() |
à Aleph69:
c'est vrai que le cour explique bien mais les instructions openMP en fortran et en C++ sont très différentes donc j'arrive pas à le mettre en pratique mais bon je vais chercher d'autre cours. Merci quand même. |
|
|
00
|
|
|
#11 | ||
|
Membre expérimenté
![]() Ingénieur développement logiciels Inscription : mars 2009 Messages : 331 ![]() |
Bonsoir,
Si ça peut t'aider, voici un exemple simple de produit scalaire : Code :
++ Autres exemples : Réduction et autres http://people.sc.fsu.edu/~jburkardt/...mp/openmp.html |
||
|
|
10
|
|
|
#12 |
|
Membre Expert
![]() Chercheur Inscription : mars 2010 Messages : 1 143 ![]() |
Salut,
Je dirais plutôt qu'elles sont très ressemblantes mais bon... ![]() Voici un résumé des commandes openmp pour le C/C++ http://openmp.org/mp-documents/OpenMP3.1-CCard.pdf et pour le fortran http://openmp.org/mp-documents/OpenM...ortranCard.pdf |
|
|
10
|
|
|
#13 | ||||
|
Invité de passage
![]() Étudiant Inscription : octobre 2012 Messages : 25 ![]() |
Citation:
C'est juste que je pouvais pas deviner comme ça par quoi il fallait remplacer. Merci pour tes liens. Citation:
J'ai essayer Code :
#pragma omp parallel for reduction(+:truc1,truc2,truc3)
Code :
Cad perte de fps et on voit que ça fait des choses bizarre(qu'il doit y avoir des calculs qui sautent ou des erreurs; je ne sais pas) |
||||
|
|
00
|
|
|
#14 |
|
Membre Expert
![]() Chercheur Inscription : mars 2010 Messages : 1 143 ![]() |
Bon, il faut vraiment que tu prennes le temps de regarder un cours sur OpenMP. Je te donne quelques points d'entrée pour que tu démarres.
Quand tu parallélises, chaque processus possède une mémoire qui lui est propre. Un autre processus ne peut ni lire ni écrire dans cette mémoire. Les variables stockées dans cette mémoire sont dites privées. Par ailleurs, tous les processus partagent une autre quantité de mémoire dans laquelle chacun peut y lire et y écrire. Les variables stockées dans cette mémoire sont dites partagées. Quand on utilise une directive OpenMP, on spécifie si les variables sont privées ou partagées, ce que tu ne fais pas. Par défaut, une variable est souvent partagée mais ce n'est pas toujours le cas. On va considérer ta variable distance pour illustrer. Comme tu n'as rien précisé, elle est partagée. Ce qui veut dire que chaque processus met à jour sa valeur à la ligne Code :
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)+1; Code :
truc3=truc3+(G*A[i].masse*(A[i].z_now-A[l].z_now))/((distance)*sqrt(distance)); Prend vraiment le temps de lire un cours, au moins jusqu'au principe de la réduction. Petite remarque au passage : si tu veux de la performance, il faut paralléliser la boucle la plus externe dans la mesure où c'est possible. Cela demande parfois de modifier l'ordre des boucles ou ce qui y est fait dedans. |
|
|
10
|
|
|
#15 | |||
|
Membre expérimenté
![]() Ingénieur développement logiciels Inscription : mars 2009 Messages : 331 ![]() |
Bonsoir,
Citation:
Code :
|
|||
|
|
10
|
|
|
#16 | |||
|
Invité de passage
![]() Étudiant Inscription : octobre 2012 Messages : 25 ![]() |
Citation:
à bretus Citation:
J'ai essayé et ça marche. Ça reste stable. L'histoire des fps c'est que enfaite pour 10 "planètes" je passe de 1800 fps (sans openMP) à 1400 fps (avec openMP). Mais pour 500 planètes je passe de 40 fps (sans openMP) à 60fps (avec openMP). Donc j'imagine que la boucle doit être suffisamment importante pour que ça vaut le coup. Citation:
(Ne m'aider pas , enfin pour l'instant En tout cas merci beaucoup pour vos réponses. |
|||
|
|
00
|
|
|
#17 |
|
Membre Expert
![]() Chercheur Inscription : mars 2010 Messages : 1 143 ![]() |
Quand tu regarderas d'un peu plus près ta documentation, profites-en pour bien regarder la notion de barrière et la clause nowait, cela t'aidera à gagner en performances si besoin.
Surtout ne parallélise pas les deux boucles : c'est soit l'une soit l'autre. Conserve bien les deux versions pour comparer. Pense aussi que tu es en fait en train de manipuler une matrice de distances. Je pense que ce serait une bonne chose que tu fasses sauter ton instruction conditionnelle, soit en faisant un peu plus de calculs, soit en procédant à une fission de ta boucle interne en deux boucles. Au fait, tu as combien de coeurs? Tu peux faire de l'hyperthreading? |
|
|
10
|
|
|
#18 | ||
|
Membre expérimenté
![]() Ingénieur développement logiciels Inscription : mars 2009 Messages : 331 ![]() |
Heureux que tu sois ravy!
Ma bonté me perdra. Citation:
Avec 10 planètes, tes traitements ne sont pas assez long pour que ça vaille le coup. Citation:
|
||
|
|
00
|
|
|
#19 |
|
Invité de passage
![]() Étudiant Inscription : octobre 2012 Messages : 25 ![]() |
J'ai un Intel i5 3570K 4coeur à 3.4GHz.
De ce que je voit la http://ark.intel.com/products/65520/...up-to-3_80-GHz mon proc n'est pas capable de faire de l'hyperthreading. Mais il a une puce graphique(et j'ai une carte graphique). Du coup au début je pensai utiliser OpenCL mais je me suis dit que ça serai plus simple pour commencer avec OpenMP. |
|
|
00
|
|
|
#20 |
|
Membre Expert
![]() Chercheur Inscription : mars 2010 Messages : 1 143 ![]() |
Avec 4 coeurs tu devrais voir quelque chose c'est bon.
Tu as raison de laisser OpenCL de côté pour le moment, c'est mieux. Le GPGPU est très à la mode mais c'est dû à un marketing agressif de Nvidia qui n'est pas très honnête sur ses benchmarks... Tu pourras tester avec par la suite mais ne t'attends pas à un speed-up de 400 même si on te promet le contraire sur le papier! |
|
|
00
|
Copyright © 2000-2013 - www.developpez.com