Solaris, libmalloc et libmtmalloc
Le
JKB
Bonsoir à tous,
J'ai développé une grosse application de calcul utilisant de
nombreux threads parallèles (une histoire d'optimisation combinatoire).
Je fais actuellement tourner cette application sur des serveurs Sun à
base de T1 et de T2, tous ces serveurs tournant sous Solaris 10 Sparc.
Par habitude, lorsque je compile un programme utilisant les threads
sous Solaris, je lie avec mtmalloc. C'est une habitude depuis je ne sais
plus quelle version de Solaris où la libmalloc simple n'était pas 'thread
safe'.
Ce programme lance une bonne centaine de threads qui effectuent un
certain nombre de malloc()/free(), chaque thread durant à peu près deux
heures de temps CPU.
Je m'aperçois avec pstat qu'au fur et à mesure, certains threads (en
nombre croissant) perdent du temps de calcul effectif jusqu'à 10% de
USER et 90% de LOCK ! J'ai regardé mon code sans rien trouver. Un coup de
plockstat me donne :
root@tchaikovski # plockstat -e 5 -p 84
0
Mutex block
Count nsec Lock Caller
-
780 31732607 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`free+0x80
791 25786631 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`oversize+0x48
1 10245664 0x1007b46c0 libmtmalloc.so.1`malloc_internal+0x44
4 22585 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`oversize+0x48
3 27280 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`free+0x80
root@tchaikovski #
Ce qui est surprenant Les threads sont bloqués par mtmalloc() !
Je fais actuellement un test en virant la mtmalloc() et en utilisant le
malloc() standard de la libc. Je n'observe plus ces états LOCK.
Deux questions :
1/ est-ce un autre bug de Solaris ?
2/ si ce n'est pas un bug, quel est l'avantage de la libmtmalloc vu
qu'elle se comporte moins bien que le malloc de la libc dans un
programme multithreadé ?
Cordialement,
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
J'ai développé une grosse application de calcul utilisant de
nombreux threads parallèles (une histoire d'optimisation combinatoire).
Je fais actuellement tourner cette application sur des serveurs Sun à
base de T1 et de T2, tous ces serveurs tournant sous Solaris 10 Sparc.
Par habitude, lorsque je compile un programme utilisant les threads
sous Solaris, je lie avec mtmalloc. C'est une habitude depuis je ne sais
plus quelle version de Solaris où la libmalloc simple n'était pas 'thread
safe'.
Ce programme lance une bonne centaine de threads qui effectuent un
certain nombre de malloc()/free(), chaque thread durant à peu près deux
heures de temps CPU.
Je m'aperçois avec pstat qu'au fur et à mesure, certains threads (en
nombre croissant) perdent du temps de calcul effectif jusqu'à 10% de
USER et 90% de LOCK ! J'ai regardé mon code sans rien trouver. Un coup de
plockstat me donne :
root@tchaikovski # plockstat -e 5 -p 84
0
Mutex block
Count nsec Lock Caller
-
780 31732607 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`free+0x80
791 25786631 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`oversize+0x48
1 10245664 0x1007b46c0 libmtmalloc.so.1`malloc_internal+0x44
4 22585 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`oversize+0x48
3 27280 libmtmalloc.so.1`oversize_lock libmtmalloc.so.1`free+0x80
root@tchaikovski #
Ce qui est surprenant Les threads sont bloqués par mtmalloc() !
Je fais actuellement un test en virant la mtmalloc() et en utilisant le
malloc() standard de la libc. Je n'observe plus ces états LOCK.
Deux questions :
1/ est-ce un autre bug de Solaris ?
2/ si ce n'est pas un bug, quel est l'avantage de la libmtmalloc vu
qu'elle se comporte moins bien que le malloc de la libc dans un
programme multithreadé ?
Cordialement,
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.

Poser une question


Que penses tu de ceci:
http://ekschi.com/technology/2009/0...c-vs-umem/
--
Michel TALON
Re: Solaris, libmalloc et libmtmalloc,
Michel Talon ?crivait dans fr.comp.os.unix :
Je connaissais, mais ça n'aide pas vraiment dans le cas présent.
J'ai utilisé depuis hier soir libmalloc en lieu et place de
mtlibmalloc et ça fonctionne mieux. En revanche, le free() de
libmalloc() ne renvoie pas la mémoire au système mais à
l'application, ce qui fait que la machine se met de plus en plus à
swapper. Là, tout de suite, j'en suis à :
prstat -avl 1
...
88 bertrand 34G 7016M 87% 188:23:29 23%
soit 34 Go de swap utilisé pour une application qui n'a aucune fuite
mémoire (j'ai un debugger interne qui râle lorsqu'une zone mémoire
n'est pas libérée et surtout, sous Linux ou NetBSD, le même
programme se comporte décemment et reste cantonné dans 2 Go de
mémoire).
Je vais peut-être essayer la libumem pour voir. Question de fond :
comment faire sous Solaris (et sans utiliser mmap() parce que dans
mon cas, ce n'est pas utilisable en raison de l'alignement des
blocs) pour qu'un free() renvoie la mémoire au système et non au tas
de l'application ?
Cordialement,
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Re: Solaris, libmalloc et libmtmalloc,
Michel Talon ?crivait dans fr.comp.os.unix :
Bon... libmalloc et libumem donnent grosso-modo le même résultat. Je
pense que le problème provient de la fragmentation de la mémoire.
Comment limiter cette fragmentation ? Est-ce qu'un outil comme
jemalloc est efficace ? Ce qui est amusant (enfin, si on peut dire),
c'est que libmtmalloc n'induit pas une utilisation du swap,
simplement une latence supplémentaire. Libmalloc et libumem
provoquent une augmentation plus que significative de l'espace
d'adressage du processus.
Cordialement,
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Tu as essayé de faire tourner ton programme sur FreeBSD? si ça passe
bien, c'est que jemalloc est efficace ...
Il me semblait que tous les malloc allouent de la mémoire à un
processus, et que le free la rend au processus et non pas au système.
Eventuellement le système récupère de la mémoire plus tard quand il
trouve des pages non utilisées. Donc la performance dépend aussi de
celle du système de mémoire virtuelle. Maintenant les truc comme
jemalloc qui sont conçus pour des programmes multithreadés avec des
allocations indépendantes pour chaque thread de façon à ne pas avoir à
poser des verrous, fonctionnent en utilisant plusieurs pools de mémoire
(par exemple un par thread) et donc vont être plus consommateurs de
mémoire que des allocateurs avec un seul pool. Si ton programme utilise
en réalité peu de concurrence, il est possible que l'utilisation d'un
malloc à l'ancienne soit préférable en dépit des coûts de
synchronisation. Clairement les allocateurs modernes ont été conçus pour
des programmes fortement multithreadés avec une forte concurrence dans
l'allocation de mémoire. Dans ce cas diviser les coûts de verrouillage
est important.
Ceci peut t'intéresser:
http://benjamin.smedbergs.us/blog/tag/jemalloc/
--
Michel TALON
Re: Solaris, libmalloc et libmtmalloc,
Michel Talon ?crivait dans fr.comp.os.unix :
J'ai fait des tests. Sous Linux, la mémoire est renvoyée au système
(sauf peut-être lorsqu'elle est allouée sur le tas). Sous NetBSD et
FreeBSD, je n'ai pas fait de tests poussés, mais je suis sûr que le
programme en question tourne correctement.
Merci, déjà lu ;-)
Sous Solaris, j'ai déjà testé libmalloc, libbsdmalloc, libumem et
libmtmalloc. Tous se comportent de manières différentes, mais aucun
ne donne satisfaction. libmtmalloc n'utilise pas de swap mais pose
des verrous qui grèvent les performances, libmalloc et libumem se
mettent à swapper...
Je vais essayer LD_PRELOAD avec la libjemalloc...
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.