Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Mutex -> consomme beaucoup en ressources ?  (Lu 4818 fois)

0 Membres et 1 Invité sur ce sujet

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Mutex -> consomme beaucoup en ressources ?
« le: Juillet 29, 2012, 05:07:58 pm »
Bonjour à tous et à toutes :)

J'utilise, dans mon application serveur, 1728 mutex. Est-ce que cela nuit aux performances ? (ces mutex sont nécessaires afin d'optimiser au maximum (en théorie) la vitesse de tous (4) les threads qui interagissent régulièrement sur des données partagées)

Merci et bonne journée 8)

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #1 le: Juillet 29, 2012, 05:27:30 pm »
+

Petite question tant qu'à y être : si on fait un receive sur une socket et que ça retourne Socket::Error, est-ce que la socket est déjà déconnecté ou je dois faire socket.disconnect() pour être sûr que tout se ferme correctement ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #2 le: Juillet 29, 2012, 05:45:42 pm »
Ce n'est pas tant le nombre de mutexs qui est important, mais le nombre de fois que tu lock/unlock. Ca a un coût qui est loin d'être négligeable, donc attention à les limiter au strict minimum.

Citer
si on fait un receive sur une socket et que ça retourne Socket::Error, est-ce que la socket est déjà déconnecté ou je dois faire socket.disconnect() pour être sûr que tout se ferme correctement ?
Déconnectée c'est Socket::Disconnected ;)
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #3 le: Juillet 29, 2012, 07:21:05 pm »
Oui, mais je me disais que peut-être que si une error survient, la socket plante tout simplement... Donc je n'étais pas sûr ;)

Bien en fait tu te rappelles sûrement de mon projet. J'ai tout simplement stocké les clients dans un tableau 2d de liste :
std::list m_clients[32][18];
 

chaque parti du tableau représente une zone dans la carte. La carte (enfin une carte), c'est entièrement gérée par une machine physique.

C'est donc plusieurs threads qui accomplissent différentes tâches sur les clients qui y ont accès en même temps.

Writers threads : addClient et receivingData (uniquement si la socket est disconnected pour receiveingData. On supprime le client des lists. addClient et bien on bloque la liste pour en ajouter un)

Readers threads : processingData et updating (ces deux là ne font que lire les valeurs des joueurs et les modifier au besoin. Les variables sont séparés de façon à ce qu'ils n'utilisent pas les mêmes donc pas de lock)

Moi je me suis dit que ça serait bien que chaque thread se présente uniquement pour la zone qu'ils sont en train de lire ou écrire. Ainsi, tous les readers peuvent agir en même temps et on a un writer à la fois qui bloque uniquement la zone (les readers et même l'autre writer peuvent donc continuer de faire du traitement sur les autres zones de la carte pendant que le writer écrit dans une autre zone)

ça me donne donc des tableaux comme ça :
sf::Mutex m_lock_receivingData[32][18];
sf::Mutex m_lock_updating[32][18];
sf::Mutex m_lock_processingData[32][18];
sf::Mutex m_lock_receivedData;
 

addClient les bloque tous quand il écrit. recevingData se bloque en lecture (le premier donc) et bloque receivedData (qui est une liste des événements à traiter) s'il veut en ajouter un. les autres se bloque tout simplement lorsqu'ils sont en lecture. Il est par contre important de les bloquer dans un ordre identique pour les deux writers sinon ils pourraient s'inter-bloquer.

Donc en théorie, cette façon de faire est très optimisé. Par contre, en pratique, si ça consomme beaucoup... alors je ne sais pas trop quoi faire...

Quatre solutions :

-un à la fois sur la carte, mais là ça sert à rien d'avoir plusieurs threads.

-en sachant qu'une lecture est plus rapide qu'une écriture, on pourrait simplement utiliser un tableau et lorsqu'un writer veut écrire, il bloque la zone et lorsqu'un lecteur veut lire, il la bloque et la débloque aussitôt (pour permettre aux autres lecteurs de lire en parallèle).

-un seul tableau et peut importe qu'il s'agisse d'une lecture ou écriture, on bloque la zone.

-les variables comme en haut, mais pas en tableau. Par contre, il faudrait attendre qu'un thread en écriture ait fait le tour de la carte entière avant de pouvoir recommencer à lire... pas super...

J'espère que tu as une meilleure idée ou un simple conseil à me donner (par exemple qu'une des solutions s'avère plus rapide que ce que je prévoyais faire ou encore que la solution la plus rapide se situe dans mes choix ou dans ta tête ;D)

merci et bonne journée ! 8)

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #4 le: Juillet 29, 2012, 07:28:51 pm »
Je sais pas si c'est significatif, mais en faisant une simple boucle avec un mutex, je peux la locker et délocker 25 millions de fois par seconde... :o

De plus, en faisant une boucle de 50 000 000 dans 2 threads (donc encore 100 000 000 comme le premier test) qui lock et unlock la même mutex, je peux faire l'échange du contrôle 6.7 millions de fois par seconde.

Ça consomme beaucoup de ressource... mais jusqu'à quel point ? moi j'ai besoin de faire gros maximum 100 000 lock/unlock à travers les 4 threads par seconde.
« Modifié: Juillet 29, 2012, 07:33:47 pm par neo007 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #5 le: Juillet 29, 2012, 07:34:50 pm »
Il est difficile de rentrer dans ton projet en 2 secondes, donc malheureusement je ne pourrai pas te donner de conseil. Mais as-tu réellement des problèmes ? Si ce n'est pas le cas, alors continue le développement. S'arrêter sur des choses qui marchent mais qui pourraient potentiellement un jour poser problème, c'est une perte de temps.
Laurent Gomila - SFML developer

Samuel Proulx

  • Full Member
  • ***
  • Messages: 118
    • Voir le profil
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #6 le: Juillet 29, 2012, 08:24:12 pm »
Donc tu me conseilles de laisser ça comme ça (même si c'est pas (et sûrement pas) la meilleure façon) tant qu'elle ne me pose pas de problème de performance ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #7 le: Juillet 29, 2012, 09:06:05 pm »
Complètement.
Laurent Gomila - SFML developer

danman

  • Hero Member
  • *****
  • Messages: 1121
    • Voir le profil
    • E-mail
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #8 le: Juillet 29, 2012, 10:01:44 pm »
Une solution future serait toujours d'implémenter ton propre système de verrou, mais est-ce que ce serait significatif ? tu le verras apres.
Pointilleur professionnel

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #9 le: Juillet 29, 2012, 10:19:05 pm »
Citer
Une solution future serait toujours d'implémenter ton propre système de verrou
Tu veux dire, écrire quelque chose de plus performant que les mutexs fournis par l'OS ? C'est possible mais ça devient très chiadé, et ça requiert d'autres primitives de threading. Faire une utilisation juste des mutexs me paraît plus sage et atteignable comme solution :)
Laurent Gomila - SFML developer

danman

  • Hero Member
  • *****
  • Messages: 1121
    • Voir le profil
    • E-mail
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #10 le: Juillet 29, 2012, 11:47:17 pm »
Je ne suis pas assez pro dans ce domaine pour en juger, mais il n'existe pas d'autres formes de verrou ? ou au moins de monitoring ?
Pointilleur professionnel

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Mutex -> consomme beaucoup en ressources ?
« Réponse #11 le: Juillet 30, 2012, 08:16:29 am »
Il existe les sémaphores, qui sont juste une généralisation des mutexs. Les spin-locks, qui sont des verrous ultra-légers à attente active basés sur les entiers atomiques (utiles pour les très petites attentes où il vaut mieux ne pas envoyer le thread bloqué au dodo). Les "wait condition" qui permettent d'endormir un thread jusqu'à ce qu'un signal soit envoyé explicitement par un autre thread.

Bref il existe d'autres primitives de synchronisation, mais elles ont d'autres utilités, pas forcément de meilleures performances.

On peut rajouter une surcouche aux mutex pour les rendre moins gourmands lors des verrouillages "inutiles", comme le fait Qt avec ses QMutex, mais c'est déjà pas mal de boulot et il faut des entiers atomiques (pas dispos nativement en C++03).
Laurent Gomila - SFML developer