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 :

Mulithreading et fractale : problème de performance


Sujet :

Threads & Processus C++

  1. #1
    Membre averti Avatar de CaptainKrabs
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2018
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2018
    Messages : 25
    Par défaut Mulithreading et fractale : problème de performance
    Bonjour à tous,

    Afin de me familiariser avec le multithreading en C++, j'ai écris un code permettant de créer des images de fractale :
    https://github.com/cgindre/FractalJu...ithreading.git
    (La fonction main() est située dans le fichier fractalJulia.cpp.)

    Cependant, lorsque j'exécute mon code en faisant varier le nombre de threads, je devrais m'attendre à un gain de temps dans le temps de calcul... Cependant je ne constate aucun gain de temps.
    Voici quelques durées d'exécution obtenues suivants le nombre de threads :
    Avec 1 thread :
    Le delai d'execution vaut : 5.67352s.

    Avec 9 threads :
    Le delai d'execution vaut : 5.63341s.

    Avec 20 threads :
    Le delai d'execution vaut : 5.5258s.

    Les durées sont sensiblement les mêmes ...
    Auriez-vous une idée sur l'origine de mon problème ?
    Et comment je pourrais remédier à cela et constater une diminution dans la durée d'exécution ?

    En vous remerciant par avance de votre aide.

  2. #2
    Membre chevronné
    Homme Profil pro
    Urbaniste
    Inscrit en
    Août 2023
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Urbaniste

    Informations forums :
    Inscription : Août 2023
    Messages : 387
    Par défaut
    Il faut regarder dans votre code d'écriture du fichier. Écrire un pixel à chaque appel c'est nul.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Il y a de nombreuses erreurs dans le code (essentiellement des données mal allouées), difficile pour nous de le rejouer.

    Pour calculer la fractale, il faut quelques dizaines de millisecondes. Pour écrire le fichier, il faut plusieurs secondes. Utiliser les threads pour le calcul ne fait rien gagner ici.

    On peut voir le problème, juste en remplaçant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Image::write_color(float value)
    {
    	_fluxImg << _cs.getLinColor(value) << std::endl;
    }
    Par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void Image::write_color( float value )
    {
    	_fluxImg << _cs.getLinColor(value) << '\r';
    }
    Il devrait y avoir un gain visible, ici la fonction std::endl a un coût énorme!

    Pour optimiser plus l'écriture du fichier, on peut utiliser le PPM binaire, plutôt que le PPM texte. Chaque pixel va alors nécessiter 3 octets au lieu de 6 à 12 octets.
    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
    Image::Image(int width, int height, const char* cheminImg, bool bin)
        : _width(width), _height(height), _cheminImg(cheminImg), _bin(bin) {
    	_fluxImg.open( cheminImg, bin ? std::ios::binary : std::ios::out );
    }
     
    void Image::write_header() {
    	_fluxImg << (_bin?"P6\r":"P3\r")
    	    << _width << " " << _height << '\r'
    	    << RGB::_colorLevel << '\r';
    }
     
    void Image::write_color(float value) {
    	auto  color = _cs.getLinColor( value );
    	if ( _bin ) {
    		char  buf[3];
    		buf[0] = color._Red;
    		buf[1] = color._Green;
    		buf[2] = color._Blue;
    		_fluxImg.write( buf, 3 );
    	}
    	else
    		_fluxImg << color << '\r';
    }
    La présence des threads devrait alors se voir:
    1 thread -> ~200ms
    10 threads -> ~150ms

  4. #4
    Membre chevronné
    Homme Profil pro
    Urbaniste
    Inscrit en
    Août 2023
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Urbaniste

    Informations forums :
    Inscription : Août 2023
    Messages : 387
    Par défaut
    oui, mais du coup le tampon sous-jacent n'es plus explicitement vidé en écriture sur le système.
    J'avais pas pensé à ce destructeur.

    Bon de toutes façons faudrait commencer par corriger les RC avant de s'inquiéter d'optimiser la chose.
    Et avant d'optimiser quoi que ce soit, faudrait se soucier de son outillage et de ses méthodes de travail.

  5. #5
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 599
    Par défaut
    Bonjour,

    Multiplier les threads a, de plus, des limites. Quand je vois 20 threads, je suppose qu'il y a, par exemple, 10 unités physiques pour 20 unités logiques. Hélas, il n'y a pas de magie.

    Une tâche standard consomme de l'ordre de 70% des ressources d'une unité physique (des temps morts sont dus aux attentes mémoire, rupture du flux d'instructions, interdépendances d'instructions, attentes réponse système etc.) d'où l'idée de permettre à une unité physique de se partager en 2 unités logiques pour mieux utiliser le potentiel CPU. Mais 2x70% fait 140% ce qui est impossible donc, globalement, il y a moins de ressources par fil, en moyenne 50%. C'est d'autant plus vrai pour les threads d'une même tâche parallélisée car ses fils tendent à connaitre les même temps morts au même moment.

    Je conseillerais de ne pas dépasser le nombre de cœurs physiques. Au delà les gains diminuent assez rapidement pour même être négatifs. En effet, si tous les cœurs logiques sont utilisés, comme l'OS ne s'arrête pas pour autant, il va parasiter tel ou tel thread. Le résultat est que certains fils vont prendre du retard, et comme la fin du job suppose celle du dernier arrivé…

    Salutations

Discussions similaires

  1. [maintenance][performance] Que faire comme maintenance ?
    Par woodwai dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 06/11/2003, 15h39
  2. Performance xml
    Par MicKCanE dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 07/07/2003, 06h41
  3. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18
  4. [JDBC][connexion persistante] performances avec JDBC
    Par nawac dans le forum Connexion aux bases de données
    Réponses: 6
    Dernier message: 06/05/2003, 10h37
  5. performance entre 3DS, ase, asc ...
    Par amaury pouly dans le forum OpenGL
    Réponses: 3
    Dernier message: 24/03/2003, 11h41

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