Bonjour,
j'aimerais savoir s'il y avait des plug-in Eclipse gratuits qui servent de profiler et debugger pour du code massivement parallèle.
Je sais que pour C++ il y a Intel Parallel Studio (plug-in Visual Studio) qui le fait, mais là je cherche pour Java avec Eclipse.
Merci de me conseiller.
Par massivement parrallèle, tu veux dire une grid?
je sais qu'un projet a commencé dans un groupe de recherche de la polytechnique ou je bosse autour de g-eclipse. Si tu veux jeter un coup d'oeil mais par contre je sais pas quel middleware ils emploient dessous.
Je ne sait pas exactement ce que tu appelles une grid. Le calcul n'est pas réparti, il s'exécute sur une seule machine.
Le "massivement parallèle" c'est plus par rapport au nombre de threads (variable, la je fais mes test sur ~15000 threads).
Alors non c'est pas ce que je pensais. Oublie mon post précédent.
Sinon avec tes 15'000 je me demande ce que tu dois avoir comme machine de guerre pour que le context switching ne bute pas complètement les performances.
Sans compter l'espace d'adressage. T'es sur quel OS?
La j'ai eu des soucis avec mon PC donc je teste sur un vieux PC (pentium M 1,6 ghz, 512 Mo de ram, Windows XP) et ça rame à mort. Je pense que c'est à cause de la RAM car avec XP + Eclipse + antivirus ... je suis déjà à 512 Mo utilisés.
Je pense que sur mon nouveau PC (Core 2 duo 2,1 Ghz, 4 Go RAM, Vista et je mettrais un linux) ça ira mieux.
C'est quoi exactement le context switching?
Non attend c'est juste impossible que ce grille-pain supporte 15'000 threads. Pour info, normalement je sais pas si c'est forcé ou non dans une techno managée mais un thread a en principe besoin d'à peu près 1mo d'espace d'adressage pour bosser.
Je te laisse faire le calcul si t'as 15'000 threads, ça surpasse *légèrement* tes 512mo.
Puisqu'un processeur ne peut exécuter en principe qu'un nombre de tâche à la fois limité notamment par ses core, chaque thread peu importe le process est autorisé à utiliser un CPU pendant un certain laps temps, après quoi c'est un autre thread, éventuellement d'un autre process qui fera le sien, et ainsi de suite au tour par tour.
Changer de thread nécessite de restaurer son contexte, son état si tu veux. C'est ça le context switch.
C'est un peu plus compliqué que ça mais ça te donne une idée...
Je sais que ça dépasse les 512 Mo, le programme utilise une bonne partie du fichier d'échange, et encore, il n'arrive pas à lancer tous les threads. Mais mon objectif initial était d'atteindre ces 15000 thread.
Pour la moment avec mon vieux portable, j'arrive à faire tourner au moins 5000 threads (sauf erreur dans mon code, ceux la arrivent à ce lancer) mais ça avance lentement.
C'est pas possible... Ou alors la jvm s'arrange pour tricher la limite dieu sait comment.
Quoi qu'il en soit je sais pas ce que tu essaies de faire, mais je suis persuadé que ton architecture est totalement à revoir.
Pour prendre un exemple, le serveur websphere d'IBM considéré comme un des poids lourds de sa catégorie utilise par défaut un pool de 40 threads, que tu peux à peu près pousser à 75 avec un heap de 2 bons gigas. Et c'est fait pour tourner sur des machines de brute.
J'espère que ça te montre à quel point t'es dans l'erreur avec tes 5000-15000 threads sur ton petit portable.
C'est pour une simulation multi-agent, et normalement il devrait pas y avoir de problème. En tout cas des programmes avec plusieurs 100aines de thread j'ai déja fait sur mon portable en panne (core 2 duo 1,66 Ghz, 2 go RAM, Vista 32 bits).
Tu bosses avec repast?
Sinon je vais m'absenter un moment, une centaine de threads c'est tout à fait possible. C'est juste que ça veut pas dire que ce soit efficace si le hardware est pas fait pour.
Holy shit. 15000 threads. Il n'y a pas de machine de bureau au monde qui supporte un truc comme ca. Je ne sais pas comment ca marche les thread en java, mais ce n'est pas impossible qu'au bout d'un moment la JVM ne fasse plus des thread noyau mais des thread utilisateurs pour avoir des contexte switch plus leger.
Au niveau du systeme, un thread ce n'est pas bien different d'un processus. Tu t'imagine lance 15000 processus en meme temps ? meme si il y en a 95% qui sont en attente d'entree/sortie, ca laisse 750 processus qui calcul en meme temps. C'est juste trop
Au niveau du debuggage, je ne sais pas bienc omment ca marche ne java. Mais en C, le debuggage marche en parallele comme en sequentiel. Tu accorche gdb, tu met des break points et quand l'un est touche, tout le monde s'arrete. Pour le profiling parallele gprof, cachegrind ca marche toujours pareil. Pour la verification memoire, valgrind replie les tous les threads sur un seul processeur. Donc ca rends le code encore plus lent que d'habitude dans valgrind
mais la encore, ca marche pareil.
C'est visiblement pas ton cas ici (15000 thread et du java), mais en calcul haute performance, les problemes viennent souvent de la synchronisation a grain fin, des contentions sur les bancs memoire et cie. Ce n'est plus possible d'utiliser des profileurs/debuggeurs standard a ce niveau, ils sont trop intrusif. Il faut utiliser des outils que tu ecris pour le cas. Et tu utilise les registre de debuggage et performance du processeurs. Souvent ils ne sont pas exporte par defaut dans les noyau et il faut les patcher pour y avoir access (PAPI dans le cadre de linux, mais je crois qu'il est en passe de devenir obsolete)
J'utilise le plug-in MAY pour créer mes agents: http://www.irit.fr/MAY
Mes threads sont gérés par un gestionnaire de thread qui fait faire un pas à chaque agent en même temps. Quand l'agent a fait son pas, il se met en attente. Quand ils ont tous fini leur pas, un nouveau pas est lancé.
Pour le debug, c'est plus un outil qui trouve les deadlocks, livelocks, ou mauvaise gestion de l'exclusion mutuelle qu'il me faut.
Je ferais de tests sur mon nouveau portable pour voir la limite de threads que je peux atteindre.
"Mes threads sont gérés par un gestionnaire de thread qui fait faire un pas à chaque agent en même temps. Quand l'agent a fait son pas, il se met en attente. Quand ils ont tous fini leur pas, un nouveau pas est lancé."
Si c'et vraiment ca que tu veux faire, ce qu'il te faut c'est une machine parallele, c'est pas un ordinateur de bureau. Tu es quasiment sur qu'a chaque contexte switch tu fais un access en RAM. Parceque ca me parait clair que ca ne tiens pas en cache tout ca.
"Pour le debug, c'est plus un outil qui trouve les deadlocks, livelocks, ou mauvaise gestion de l'exclusion mutuelle qu'il me faut. "
Il y a des outisl statique qui servent a detecter les deadlocks. Je sais qu'il y a des gens qui travaillent ou ont travaille la dessus. Mais je ne sais pas si il y a eu un logiciel de produit. Si tu peux surcharger la fonction de lock, c'est assez facil de detecter les deadlock quand ils arrivent. Il suffit de construire le graphe des ressources/thread et de chercher un cycle dedans.
Qu'est ce que tu appelle un livelock ?
Des outils qui detecte une mauvaise gestion de l'exclusion mutuelle, ca m'etonnerait que ca existe. Parceque potentiellement tu peux le faire express d'acceder a la meme donne a partir de plusieurs threads de calcul. Puet etre des outils de memoire transactionnelle te permettrait de detecter ca cependant...
"Si c'et vraiment ca que tu veux faire, ce qu'il te faut c'est une machine parallele, c'est pas un ordinateur de bureau. Tu es quasiment sur qu'a chaque contexte switch tu fais un access en RAM. Parceque ca me parait clair que ca ne tiens pas en cache tout ca. "
Je n'ai de machine parallèle sous la main
. La démarche est plus importante que le résultat, donc si ça passe pas, je diminuerais le nombre d'agent. Mais les besoins en performance ne sont pas énormes: la simulation dure le temps nécessaire, il n'y a pas de temps réel.
Un livelock c'est des processus s'exécutent sans limite et empêche d'autre processus d'avoir accès au CPU. A priori avec mon gestionnaire de thread je devrais pas avoir ce genre de problème. C'est surtout l'exclusion mutuelle qu'il faut que je surveille.
Tu peux pas créer un pool de thread puis placer les déplacements dans une file en tant que workitems? Tu as d'excellentes API en java pour faire ça.
Déjà ça réduit énormément l'overhead nécessaire à la création de threads, c'est 100 fois plus maîtrisable et paramétrable que cet espèce de truc bizarre qui prétend tout exécuter en même temps.
Ce qu'il faut bien imaginer, c'est que les threads font gagner du temps jusqu'à un certain stade optimale, passé ce stade, en rajouter dégrade les performances.
Surtout sur un ordi de chez carouf sans vouloir manquer de respect à ta bécane.
Sinon pour ton projet, je te conseille de considérer repast, j'ai fait mon travail de diplôme avec. T'as une foule de librairie pour bosser sur des graphes, des grilles rasters ou du SIG, en plus t'as l'intégration de terracotta.
"Je n'ai de machine parallèle sous la main
. La démarche est plus importante que le résultat, donc si ça passe pas, je diminuerais le nombre d'agent. Mais les besoins en performance ne sont pas énormes: la simulation dure le temps nécessaire, il n'y a pas de temps réel."
Temps-reel et avant-noel ca rime mais ce n'est pas la meme chose
Ce genre de probleme multiplie facilement les temps de calcul par mille. C'est sur que pas d'optimisation premature est un bon principe.
Quelle est la difference entre un livelock et de la starvation ( famine ) ?
"Quelle est la difference entre un livelock et de la starvation ( famine ) ? "
C'est la même chose ![]()
ok
quelques pistes.
Tu as 15 000 thread java de cree, mais combien de threads sont cree dans le noyau ? Avec un peu de chance, java fait des threads utilisateurs et pas des threads noyau ce qui serait preferable dans ton cas .
Aussi, je ne sais pas comment marchent les locks en java. Dans les systemes unix, le standard est au futex, basiquement, quand tu rentre en attente sur un lock, tu fais quelques etapes d'attente active avant de rentrer en attente passive. Vu ton cas, tu ne veux probablement pas d'attente active, essaye de voir si tu as des regleages quelques part qui te permettent de faire ca.
Au niveau de la famine en C, c'est facil a detecter, il suffit de surcharger la libc pour les operations mutex_lock et mutex_unlock en rajoutant un timer. Si ce timer depasse x millisecondes, tu met un message dans un log.
Sinon, je plussoie _skip sur les workitem. Je ne connais pas la terminologie java, mais si tu as de la synchronisation en etapes, tu prefere probablement avoir autant de thread que de processeur sur ta machine qui se partage le travail et qui execute sequentiellement les etapes elementaire de tes differents agents.
Basiquement ce dont tu as besoin c'est d'un for_parallel a la openmp.