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 :

Multi-thread, Mutex et performances


Sujet :

C++

  1. #1
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut Multi-thread, Mutex et performances
    Bonjour,

    Je travaille actuellement sur une application qui est chargée en tant que "plugin" au sein d'une application "hôte".

    Mon plugin se compose d'une hiérarchie d'objets "métier", éditée par une IHM qui tourne dans son propre thread.

    En gros, ma hiérarchie ressemble à ça (elle est créée par l'utilisateur qui y ajoute des objets) :

    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
    -- Session
      | 
      |-- Groupe 1
      |   |
      |   |-- Objet 1.1
      |   |-- Objet 1.2
      |      |
      |      |-- Composant 1.2.1
      |      |-- Composant 1.2.2
      | 
      |-- Groupe 2
      |   |
      |   |-- Objet 2.1
      |   |  |
      |   |  |-- Composant 2.1.1
      |   |  |-- Composant 2.1.2
      |   |
      |   |-- Objet 2.2
    Ensuite, le logiciel "hôte" utilise un thread qui vient parcourir l'ensemble de cette hiérarchie pour en sortir des données. Ce thread doit être "prioritaire" sur le thread GUI car le traitement a lieu pratiquement en temps réel.

    Vu que l'utilisateur (le thread IHM) peut modifier la hiérarchie ou les propriétés d'un objet pendant que le thread de calcul tourne, faut synchroniser tout ça.

    (le thread de calcul ne fait que "lire" les données, le thread IHM les lit et les écrit)




    Quelle serait selon vous la meilleure méthode (en terme de performances), sachant que le thread de calcul exécute son code de traitement de la hiérarchie toutes les 10-20 ms environ ?




    J'ai pensé à ça :

    1. utiliser un mutex (et un seul) pour bloquer toute la hiérarchie.
    - par le thread de calcul : locké à chaque fois qu'il commence à lire la hiérarchie / libéré quand il a finit
    - par le thread d'IHM : locké/libéré à chaque fois qu'il traite un évènement (on bloque sa boucle de messages)

    => facile, seuls 2 endroits où mettre les lock, et peut de risque de bugs inter-thread
    => je crains de faire attendre longtemps le thread de calcul si le thread GUI est occupé (a faire un gros redraw ou une opération disque par exemple)


    2. utiliser un mutex par objet de la hiérarchie
    - par le thread de calcul : locké/libéré à chaque fois qu'il lit cet objet en particulier
    - par le thread d'IHM : locké/libéré à chaque fois qu'il lit/écrit cet objet en particulier

    => on ne risque plus d'attendre trop longtemps, car les opérations lockées sont beaucoup plus "atomiques"
    => je crains que cela fasse beaucoup de "lock/unlock" inutiles (la hiérarchie est potentiellement grosse, quelques centaines d'objets) et beaucoup de mutex


    3. un mix des deux : un seul mutex
    - par le thread de calcul : locké à chaque fois qu'il commence à lire la hiérarchie / libéré quand il a finit
    - par le thread d'IHM : locké à chaque début de modif d'un objet / libéré à la fin

    => on risque de faire attendre l'IHM un peu (mais c'est pas grave)
    => le thread de calcul ne risque pas d'attendre trop longtemps
    => cette solution me parait la meilleure, mais ça veut dire poser des lock/unlock dans chaque fonction du thread d'IHM qui édite les objets
    => y'en a beaucoup, je crains d'en oublier et de voir apparaître un bug incompréhensible de temps à autre à cause d'un soucis de synchro


    Tous vos conseils seront les bienvenus !

  2. #2
    Débutant
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Points : 176
    Points
    176
    Par défaut
    peut être essaye d'utiliser un seul mutex, et réévalue si tu as des soucis de perf

  3. #3
    screetch
    Invité(e)
    Par défaut
    tu pourrais travailler sur une copie. L'IHM travaille sur une copie offline.
    A chaque fois que tu fais un changement, lorsque ce changement est "committé" par l'utilisateur, l'IHM remplace l'arborescence par la nouvelle.
    En gros:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    static Arborescence* current;
    static Arborescence* next;
    static Arborescence* work;
    * Thread de calcul:
      - if next: current = next; next = 0; /* cette opération peut être atomique, mais au pire tu lui colle un mutex */
      - faireCalcul(current); /* rien ne peut interrompre, current est privé a ce thread, super rapide */
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    * Thread IHM:
      - lors du commit:
        - Arborescence* copy = work;
        - Arborescence* old = replace(next, copy); /* c'est atomique aussi, old contient la valeur précédente */
        - delete old (au cas ou c'est différent de 0)
    c'est sans mutex, sauf peut être des opérations assez courtes si tu as pas envie d'utiliser les opérations atomiques qui sont un peu spéciales.

    test deux trheads utilisant des copies bien séparées, rien ne peut les interrompre

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Sinon, en termes de performances et si ton architecture le permet, une section critique est moins gourmande qu'un mutex.

    L'inconvénient, c'est qu'une section critique est inter thread only alors que le mutex est inter process (c'est un objet du noyau)

  5. #5
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Merci pour ces quelques pistes...

    @screetch : c'est vrai que je n'avais pas envisagé cette solution... mais le surcoût mémoire d'une copie me parait assez élevé, faut que je teste voir si c'est envisageable.


    @ram-0000 : dans mon archi, c'est uniquement inter-thread, donc ce serait possible. Par contre je ne suis pas sûr de bien comprendre quel code protéger dans ma section critique

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par buzzkaido Voir le message
    @ram-0000 : dans mon archi, c'est uniquement inter-thread, donc ce serait possible. Par contre je ne suis pas sûr de bien comprendre quel code protéger dans ma section critique
    Tu protèges le code de toutes les fonctions de manipulation de ta ressource critique. En fait, la section critique protège le code de manipulation de ta variable à protéger. Il faut bien sûr que les manipulation de cet objet à protéger passe par des fonctions de manipulation, sinon, cela sert à rien.

    Ta section critique est une variable globale (ou à visibilité limitée si tu peux). Dès que tu entres dans une fonction de manipulation de ton objet à protéger, tu lock ta section critique, dès que tu quittes, tu unlock ta section critique.

    Ce lock de section critique peut même être une variable locale de ta fonction qui travaille sur la section critique globale. Ainsi, si une exception est levée dans ta fonction, ta variable lock sera détruite et donc la section critique sera libérée automatiquement.

  7. #7
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    L'inconvénient, c'est qu'une section critique est inter thread only alors que le mutex est inter process (c'est un objet du noyau)
    La signification n'est pas la même suivant les plateforme et framework...

    Tu développe sous quel os et avec quel framework?

  8. #8
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    @yan : multi-os, avec Qt

    EDIT : oups, double post...

  9. #9
    Débutant
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    688
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 688
    Points : 176
    Points
    176
    Par défaut
    de rien

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par buzzkaido Voir le message
    @yan : multi-os, avec Qt

    EDIT : oups, double post...
    Donc zone critique c'est un mutex ^^
    Regarde si les QReadWriteMutex ne pourrai pas être intérresant.

  11. #11
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Oui les "QReadWriteMutex" correspondent assez bien au besoin.

    Ce que je pose plus comme question, c'est :

    "où placer mes mutex (quelque soit le type) pour que ce soit efficace ?"

    Par efficace, j'entends :
    - pas de risque d'attente longue pour le thread "hôte"
    - pas de risque que le thread IHM n'obtienne presque jamais la main car le thread "hôte" est en train de bourriner
    - simplicité de mise en oeuvre pour éviter les erreurs humaines (surtout dans un contexte multi-thread, le débogage, c'est chôchô les marrons)

    Ma première idée :
    1. utiliser un mutex (et un seul) pour bloquer toute la hiérarchie.
    - par le thread de calcul : locké à chaque fois qu'il commence à lire la hiérarchie / libéré quand il a finit
    - par le thread d'IHM : locké/libéré à chaque fois qu'il traite un évènement (on bloque sa boucle de messages)
    est très simple a mettre en oeuvre, mais je pense qu'il y a un un risque assez élevé d'attente longue à la fois pour le thread "hôte" et le thread "IHM"

    Les 2 autres solutions me paraissent plus efficaces, mais avec un risque humain plus élevé.

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    peut être un read-write mutex sur certain noeud précis de ton arbre?

  13. #13
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    En général, je privilégie les tâches qui communiquent via queues de messages.

    Je ne peux que te conseiller la lecture des (nombreux) articles d'Herbb Sutter sur le sujet (du MT), sur le site du ddj.

  14. #14
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Aurais-tu quelques liens sous la main ?

  15. #15
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut
    http://www.google.fr/search?q=sutter+thread
    Ou encore gotw, et suivre les liens.

  16. #16
    Membre éclairé
    Avatar de buzzkaido
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2004
    Messages
    821
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2004
    Messages : 821
    Points : 734
    Points
    734
    Par défaut
    Cool, de la lecture !

    Merci !

  17. #17
    screetch
    Invité(e)
    Par défaut
    sinon pour en revenir a la copie, tu peux peut être réaliser une copie plus "locale" au lieu de dupliquer tout l'arbre. A chaque étage tu pourras vérifier si le noeud courant est a jour, sinon le remplacer.
    Si les noeuds enfants peuvent être partagés, un systeme de compteur de référence permettra en lus de ne dupliquer que le noeud actuel sans dupliquer les enfants.

  18. #18
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 354
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 354
    Points : 1 419
    Points
    1 419
    Par défaut
    je pense que la copie est la seule manière elegante pour ce genre de cas.
    comme dit screetch, ajuster la granularité pour eviter trop de perte.

  19. #19
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    De la même manière que Luc, je pense qu'une file d'attente de message, qui informerait le thread de traitement de modifications à effectuer demandées par la gui, thread de traitement qui effectuerait les modifications quand il en a le temps, serait préférable dans ce cas. Sinon, tu as la quasi certitude de bloquer ton lecteur un jour ou un autre.

Discussions similaires

  1. multi-threads : mutex et conditons
    Par salseropom dans le forum C
    Réponses: 3
    Dernier message: 16/12/2007, 22h31
  2. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  3. [Multi-threading] Probleme avec les mutex
    Par homeostasie dans le forum Visual C++
    Réponses: 2
    Dernier message: 07/03/2007, 10h00
  4. [VB6][active x] faire du multi-thread avec vb
    Par pecheur dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/05/2003, 12h01
  5. [Kylix] exception qtinft.dll et multi-threading
    Par leclaudio25 dans le forum EDI
    Réponses: 3
    Dernier message: 27/03/2003, 18h09

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