Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1784 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Boost::thread => perte de perf

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Boost::thread => perte de perf

n°2113276
T'CHATTE
Posté le 25-11-2011 à 15:50:40  profilanswer
 

Bonjour à tous!
 
Voilà j'ai essayé de paralléliser un petit bout de code tout bête :
 

Code :
  1. template<class T>
  2. void coefficient(vector<T> &v, const vector<T> &up, const int nptot, const double dt)
  3. {
  4. for (int i=0; i<nptot; ++i)
  5.  {
  6.  v[i].x1()=dt*up[i].x1();
  7.  v[i].x2()=dt*up[i].x2();
  8.  }
  9. }


 
Donc il s'agit principalement de remplir un vecteur à partir d'un autre avec un traitement extrêmement simple entre les 2.
Pour paralléliser ça, j'ai fait ça (attention les yeux, je suis pas expert de code parallèles  :D ):
 

Code :
  1. class coeff
  2. {
  3. public:
  4.  coeff(){};
  5.  ~coeff(){};
  6.  template<class T>
  7.  void coefficient(vector<T> &v, const vector<T> &up, const double dt, const int indstart, const int nb_ind)
  8.   {
  9.   const size_t indend=indstart+nb_ind;
  10.   for (size_t i=indstart; i<indend; ++i)
  11.    {
  12.    v[i].x1()=dt*up[i].x1();
  13.    v[i].x2()=dt*up[i].x2();
  14.    }
  15.   }
  16. };
  17. template<class T>
  18. void coeff_parallel(parameters<double> &param, vector<T> &v, const vector<T> &up, const int nptot, const double dt){
  19. int indstart=0;
  20. int nb_ind=nptot;
  21. poscoeff V;
  22. const size_t nb_threads=param.nb_threads;
  23. boost::thread_group threads1;
  24. for (std::size_t n=0; n<nb_threads; ++n)
  25. {
  26. nb_ind=(int)((double)nptot/(double)nb_threads);
  27. if(n<nptot%nb_threads)++nb_ind;
  28. if(n>=nptot%nb_threads)
  29. {
  30. indstart=n*nb_ind+nptot%nb_threads;
  31. }
  32. else
  33. {
  34. indstart=n*nb_ind;
  35. }
  36. threads1.create_thread(boost::bind(&coeff::coefficient<T>, boost::ref(V), boost::ref(v), boost::ref(up), dt, indstart, nb_ind));
  37. }
  38. threads1.join_all();
  39. }


 
Et donc là il s'avère que c'est plus lent que la bête boucle à la ***  :sol:  
Donc je voulais savoir si c'est que j'ai une connerie quelque part ou bien juste qu'ici, comme il s'agit principalement d'accès mémoire, au final ça marche mieux en séquentiel?
 
Merci  :jap:


Message édité par T'CHATTE le 25-11-2011 à 15:52:15
mood
Publicité
Posté le 25-11-2011 à 15:50:40  profilanswer
 

n°2113308
Joel F
Real men use unique_ptr
Posté le 25-11-2011 à 20:19:21  profilanswer
 

quelle qté de donnée par thread, cb de thread ? gaffe au false sharing et au acces cache foiruex

n°2113320
Lightness1​024
Posté le 25-11-2011 à 22:56:01  profilanswer
 

franchement plus simple en openmp ce cas la.
et sinon un petit tour coté wikipedia pour chercher 'protocole MESI'

n°2113344
T'CHATTE
Posté le 26-11-2011 à 10:53:55  profilanswer
 

Joel F a écrit :

quelle qté de donnée par thread, cb de thread ? gaffe au false sharing et au acces cache foiruex


 
Pour l'instant chaque vecteur contient environ 5000 a 10000 doubles mais ensuite il y en aura dans les 100000. Le tout réparti sur 8 threads.
Qu'entends-tu par false sharing et au acces cache foireux?
 

Lightness1024 a écrit :

franchement plus simple en openmp ce cas la.
et sinon un petit tour coté wikipedia pour chercher 'protocole MESI'


 
Disons que comme j'utilise déjà Boost pour d'autres choses, je me suis dit autant continuer avec. Et il me semble que mon code ressemble à la version Static d'une boucle OpenMP non ?
Et pour MESI j'ai moyennement compris le rapport avec le schmilblick.  :??:

n°2113345
T'CHATTE
Posté le 26-11-2011 à 11:07:58  profilanswer
 

Je viens de regarder un peu le false sharing (du coup je vois mieux le rapport avec MESI) et donc en fait faire des copies locales pour chaque thread pourrait résoudre le problème apparemment ... mais je trouve que la parallélisation perd de son intérêt dans ce cas. Il n'y a pas de méthode un peu plus jolie pour contourner ca ? Et est ce que OpenMP gère ca tout seul ?

n°2113351
Un Program​meur
Posté le 26-11-2011 à 13:18:13  profilanswer
 

T'CHATTE a écrit :


 
Pour l'instant chaque vecteur contient environ 5000 a 10000 doubles mais ensuite il y en aura dans les 100000. Le tout réparti sur 8 threads.


 
Il me semble que tu ne donnes pas grand chose à faire à tes threads.  Mesure une fois le temps qu'il faut pour lancer 8 threads qui retournent immédiatement et puis faire un join dessus...


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°2113352
Lightness1​024
Posté le 26-11-2011 à 13:24:06  profilanswer
 

oui le tout est de juger l'overhead. tu peux aussi faire l'essai en charge pleine (avec 100000) et mesurer le temps pris avec une boucle sans thread, par rapport a ta version 8 threads.
aussi, openmp ne fera pas de copies automatiques pour eviter les synchro de lignes de cache. tu ne gagnes rien par rapport a ton code, et oui, tu as raison ce que tu as fait correspond a un parrallel for a schedule static.
je le préconisait juste parce que ca réduit quand même de moitié le nombre de lignes :)


---------------
http://projets.6mablog.com/
n°2113534
T'CHATTE
Posté le 28-11-2011 à 10:37:54  profilanswer
 

Bon je viens de tester quelques trucs (copie locale, utilisation d'itérateurs, ordre de parcours des vecteurs, ...) mais rien y fait : je pers toujours du temps quand j'augmente le nb de threads ...
J'imagine qu'il n'est pas possible de paralléliser un traitement aussi simple qui se résume essentiellement à des accès mémoire. Dommage :)
 
Merci pour votre aide en tout cas :jap:
A+! :hello:

n°2113538
Un Program​meur
Posté le 28-11-2011 à 10:50:12  profilanswer
 

Tu as combien de core? Avoir plus d'une thread par core n'a aucune chance d'etre interessant.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°2113556
Lightness1​024
Posté le 28-11-2011 à 12:49:53  profilanswer
 

sachant qu'il a aussi raison, a partir du moment où le jeu de donnée dépasse le cache L2 des coeurs, il faut aussi que le bus soit accessible en parallele. ce qui n'est pas le cas sur les quad core Qxxxx par exemple. mais seulement sur les Xeon et les core i7. chez AMD ca l'a toujours été par contre, c'est la raison de la grande adoption des opterons sur les serveurs.
 
si je ne dis pas de bêtises.


---------------
http://projets.6mablog.com/
mood
Publicité
Posté le 28-11-2011 à 12:49:53  profilanswer
 

n°2114968
T'CHATTE
Posté le 05-12-2011 à 17:20:46  profilanswer
 

Désolé je n'avais pas vu les réponses :jap:
 
J'ai 8 cores disponibles avec 16Go de RAM partagée. Donc j'ai déjà parallélisé pas mal de choses dans mon code et ça va beaucoup plus vite. Je me demandai juste s'il était aussi possible de gagner quelque chose sur ce genre d'opération très simple mais apparemment non.
 
Et le type de processeur est Intel Xeon X5472. Donc les Xeon n'ont pas l'air d'avoir l'accès parallèle non plus :P (ou alors ca ne suffit pas pour ce que je veux faire :??: )

n°2117682
in_your_ph​ion
Posté le 21-12-2011 à 11:50:10  profilanswer
 

En fait comment est ce que tu mesures que c'est plus lent ?

n°2117706
T'CHATTE
Posté le 21-12-2011 à 14:30:08  profilanswer
 

Avec time. Les tests que j'ai fait duraient une 12-aine de minutes et j'avais environ 35 - 40s d'écart (tout à fait reproductible, à 5s près) quand je faisais avec ou sans thread.

n°2117822
theshockwa​ve
I work at a firm named Koslow
Posté le 21-12-2011 à 23:53:51  profilanswer
 

gaffe à ne pas créer tes threads et les détruire àchaque fois que tu en as besoin. Si ca entre dans ta mesure, tu dois pouvoir te débrouiller avec un pool de threads.
 
Ca peut être pas mal de considérer que tu as un pool de jobs à faire, tous ayant le même code, ,mais des datas différentes à faire
et d'utiliser un nombre de thread correspondant à ce que ton matériel te propose.
 
Surcharger une machine de threads n'est pas une bonne idée. Les créer à chaque utilisation non plus. Ce sont les deux grosses guidelines que je peux donner à ce sujet.
 
edit : pour clarifier : si tu as une machine avec 8 threads hardware, ca peut être une bonne idée de créer 8 threads et de leur faire traiter tes 200 jobs au fur et à mesure qu'ils achèvent le boulot plutôt que de créer en frontal 200 jobs et laisser l'OS se démerder.


Message édité par theshockwave le 22-12-2011 à 00:03:07

---------------
last.fm
n°2117826
T'CHATTE
Posté le 22-12-2011 à 00:45:03  profilanswer
 

oui j'ai fait attention à ça. Ailleurs dans mon code j'ai imposé la condition :
 

Code :
  1. if(params.nb_threads>boost::thread::hardware_concurrency())
  2. {
  3. params.nb_threads=boost::thread::hardware_concurrency();
  4. }


Je ne l'avais pas mis dans le code que j'ai posté car c'est ailleurs dans mon code mais c'est bien présent :)
Et dans le oute j'avai essayé d'imposer plusieurs nombres, de 1 à 32 (alors que je n'ai que 8 cores) et dés qu'il y en a plus de 1 je pers du temps. Et plus j'ajoute des threads plus je pers du temps...

n°2117832
theshockwa​ve
I work at a firm named Koslow
Posté le 22-12-2011 à 02:58:41  profilanswer
 

mmh, c'est sympa de te plaindre de la lenteur de tes threads dans un contexte différent de celui que tu nous présente. Dans ma boule de cristal, je ne vois pas plus de choses que ce que j'ai dit plus haut.
 
Si tu ne veux pas donner le code qui te pose vraiment problème, fais du profiling.
Mesure en terme de proporition le temps que tu passes dans des appels systèmes pour créer les threads et le temps que tu passes à exécuter chaque thread. regarde si les ordres de grandeurs sont proches, parce que je soupçonne que ce sera le cas.


---------------
last.fm

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Boost::thread => perte de perf

 

Sujets relatifs
Multithread générique[prog réseaux]serveur multithread et variable globales
FTP multithreadMultithread/core avec Qt
[JAVA] Caster un objet a une classe generique ?SpinnerAdapter générique
Quelles opérations courantes sont sûres en multithread ?Templates et tableau générique
question sur static et multithread 
Plus de sujets relatifs à : Boost::thread => perte de perf


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR