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

C++ Discussion :

problème performances multithread vs monothread


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de lyxthe
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 115
    Par défaut problème performances multithread vs monothread
    Bonjour à tous, je reviens encore avec un problème de performance d'un programme que je développe en multithread à l'aide de la librairie boost_thread.

    Dans ce programme je lance un thread_group de cette façon là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	for(i=0;i<nbr_proc;i++){
    		group.create_thread(boost::bind(fonc_matr,i)); 
    	}
    	group.join_all();
    avec la fonction fonc_matr qui est égale à ça :
    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
    void fonc_matr(int num){
    	long lig,col,siz,siz_2,deb,fin;
    	siz=lis.size();
    	siz_2=siz-(siz%nbr_proc);
    	deb=(siz_2/nbr_proc)*num;
    	if(num+1!=nbr_proc){
    		fin=(siz_2/nbr_proc)*(num+1);
    	}else{
    		fin=siz;
    	}
    	minm3[num]=inf;
    	for(lig=deb;lig<fin;lig++){
    		for(col=0;col<siz;col++){
    			if(arc(lis[lig],lis[col])){
    				Matr[lig][col]=lis[col].cout;
    				Matr2[lig][col]=lis[col].cout;
    				if((minm3[num]==inf)||(minm3[num]>lis[col].cout)){
    					minm3[num]=lis[col].cout;
    				}
    			}else{
    				Matr[lig][col]=inf;
    				Matr2[lig][col]=inf;
    			}
    		}
    		if(fin-deb<100){
    				cerr <<"calcul matrice " << nummatr << ", thread "<< num+1 << "/" << nbr_proc << " : " << ((lig-deb)*100)/(fin-deb)<<"%" << endl;
    		}else{
    			if(lig%((int)(fin/100))==0){
    				cerr <<"calcul matrice " << nummatr << ", thread "<< num+1 << "/" << nbr_proc << " : " << ((lig-deb)*100)/(fin-deb)<<"%" << endl;
    			}
    		}
    	}
    	cerr <<"calcul matrice, thread "<< num+1 << "/" << nbr_proc << " : terminé " <<endl;
    }
    La donnée nbr_proc est une variable globale que je change selon mes tests. Si elle est de un, un seul thread est créé, sinon plusieurs.

    Mon problème est qu'en multithread, j'ai l'impression que les performances que j'obtiens ne sont pas celles auxquelles je pourrais m'attendre.

    Pour vous donner une idée j'obtiens ceci dans le visionneur de ressource en mono thread, ce qui me parait correcte :


    et voici ce que j'obtiens en multi :



    Dans ces graphiques, le carré en haut à gauche signal la charge CPU user des 4 procs, en haut à droite, la charge CPU system, en bas à gauche, la charge CPU inactive.

    Ma question est la suivante, est-ce que ça vous parait logique qu'en multi les procs ne soient pas à 100% de charge comme le proc unique qui tourne en monothread?

    Au vu de ces informations et du code, pensez vous que je me sois planté quelque part dans la programmation ?

    Merci pour ceux qui auront le courage d'avoir lu jusque là, en attendant vos réponses avisées.

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Par défaut
    Ma réponse est juste une idée. Je vois que tu utilises beaucoup de cout (je suppose que matrice.cout est un cout). Il se peut que les entrées/sorties bloquent le programme (mutex au niveau des fichiers ?, vitesse des bus), ...
    Enlève-les et refaits tes test. Si tu as le même résultats, cherche une fonction qui nécessiterais des mutex/semaphores/bus, ...
    Bonne chance.

  3. #3
    Membre confirmé Avatar de lyxthe
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 115
    Par défaut
    Tout l'intérêt de la parallélisation dans mon cas est justement de ne pas faire de synchronisation entre mes thread, tout est fait pour qu'ils ne lisent pas un emplacement qu'un autre est en train de modifier. Du coup je n'utilise pas de mutex.

    Je rajouterai qu'après différent tests, le programme se comporte de la même façon avec pthread qu'avec boost_thread.

    Est-il possible que la compilation de mon code donne un programme qui demande aux systèmes des synchronisations régulièrement sans que je l'ai demandé.

    J'utilise de nombreuses variable globales, dont l'accès, normalement, n'est pas synchronisé, mais je ne comprend pas pourquoi ma charge CPU système est aussi importante, alors que ma charge CPU user l'est si peu.

    De plus le programme tourne beaucoup plus vite en monothread, le comble. J'exécute mes tests ainsi : time ./a.out
    le retour de cette commande dans le bash me donne un temps reel, un temps user et un temps système, en mono le temps système est nul alors qu'en multi il est énorme.

    Bref je ne comprend pas pourquoi mon programme n'est pas plus rapide en multithread qu'en monothread, et pourquoi diable il donne ces charges CPU.

    Help

    PS : autant les mutex je vois à peu près ce que c'est, les sémaphore j'en ai une idée très vague, mais les bus, tu es le premier qui m'en parle. Peux-tu m'en dire plus, ou me dire où je peux trouver des infos ?

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    J'ai pas le temps de regarder en detail, mais j'ai quand meme vu qqch. Je ne suis pas sur que ca explique tout ce que tu experimentes. A la place d'utiliser partout minm3[num], utilise une variable locale et assigne dans le tableau juste avant de sortir du thread. Pour plus de details pourquoi, cherche "false sharing".

  5. #5
    Membre confirmé Avatar de lyxthe
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    115
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 115
    Par défaut
    Merci, apparemment effectivement, avec le peu que j'ai regardé, ça a l'air d'être une bonne piste. Je vais creuser et je reviens vous dire ce qu'il en est

  6. #6
    Membre Expert Avatar de Astraya
    Homme Profil pro
    Consommateur de café
    Inscrit en
    Mai 2007
    Messages
    1 048
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Consommateur de café
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2007
    Messages : 1 048
    Par défaut
    Pour allez plus loin, utiliser std::for_each + foncteur pour éviter l'incrémentation de long à chaque boucle.
    Ou si tu veux garder les boucles for, utilise ++lig et ++col, tu économise aussi une copie en mémoire du à la post-incrémentation.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 15
    Dernier message: 19/02/2007, 14h13
  2. Réponses: 2
    Dernier message: 24/05/2006, 13h30
  3. Réponses: 1
    Dernier message: 24/05/2006, 12h46
  4. Réponses: 7
    Dernier message: 21/11/2005, 14h21
  5. Problème performance SELECT avec jointure
    Par Netgamer dans le forum Requêtes
    Réponses: 7
    Dernier message: 05/08/2005, 10h20

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