Façons de visualiser les données d'événements à la recherche de problèmes de performances

10

J'essaie d'optimiser une application MPI avec un modèle de communication hautement asynchrone. Chaque rang a une liste de choses à calculer et envoie des messages si nécessaire si les entrées ou les sorties résident sur un rang différent. De plus, chaque rang est fileté (actuellement avec un fil de communication et 5 travailleurs).

J'ai instrumenté le code avec des minuteries autour des différentes parties critiques du code de performance, ce qui me donne une liste de triplets (début, fin, type) pour chaque thread. Tracé de manière évidente, avec le temps comme axe horizontal, le rang et le fil comme la verticale, et la couleur indiquant ce que fait actuellement chaque fil, j'obtiens une image comme celle-ci pour 16 rangs avec 6 fils / rang:

Historique des classements et des fils de Pentago

Ma question est: quelles sont les autres façons de visualiser ces données qui pourraient aider à identifier les problèmes de performances? Quelqu'un a-t-il un type de tracé préféré qu'il utilise lors du profilage des applications asynchrones?

Cet ensemble de données est limité en ce qu'il ne connaît pas la structure du flux de données, mais j'aimerais en tirer le maximum d'informations avant d'essayer de collecter quelque chose de plus compliqué.

L'image non compressée est au cas où quelqu'un voudrait regarder autour (elle n'a pas pu être téléchargée via la route normale). Malheureusement, Firefox ne l'accepte pas même si je pense qu'il est valide, peut-être parce qu'il est tout simplement trop grand.

Geoffrey Irving
la source
J'ai eu un peu de mal à charger mon navigateur ou presque n'importe quel autre programme pour charger la grande image. En fin de compte, gimp l'a fait, mais vous voudrez peut-être reconsidérer les options de taille ou de format de fichier.
Pedro
Désolé pour ça. Je pense que l'image est valide, car Firefox me donne les mêmes erreurs en cours d'exécution via convert (ImageMagick). Il dépasse peut-être un certain seuil de taille arbitraire.
Geoffrey Irving

Réponses:

4

Je passe beaucoup de temps à écrire et à déboguer du code parallèle, à la fois avec de la mémoire partagée et / ou distribuée, mais sans connaître votre problème spécifique, je ne peux que vous dire ce qui fonctionne le mieux pour moi.

Savoir quelles routines prennent combien de temps est une chose importante si vous regardez l'efficacité du calcul, mais si vous vous inquiétez de l'efficacité parallèle, alors vous devriez être plus inquiet de ce que fait votre code quand il ne fait aucun calcul. Un peu comme s'inquiéter de ce que font les enfants quand c'est trop calme ...

Puisque vous utilisez une approche de mémoire partagée / distribuée hybride, je suppose que votre code attend, dans les blancs, soit un appel MPI, soit une variable mutex / condition. Vous pouvez également encapsuler ces appels dans des minuteries, ce qui vous donnera une meilleure image de ce qui vous ralentit, par exemple si c'est toujours le même conditionnel ou toujours le même sur MPI_REDUCElequel vos threads sont bloqués.

L'un des logiciels que j'utilise assez souvent est le Intel Vtune Amplifier XE . Il a une fonctionnalité / option de traçage agréable qui visualise la simultanéité des threads. Le programme dessinera un tracé très similaire au vôtre, mais lorsqu'un thread attend sur un mutex ou une variable de condition, il trace une ligne diagonale du thread en attente, au moment où il a commencé à attendre, vers le thread qui a effectivement libéré le mutex ou signalé l'état qu'il attendait, au moment où il a été libéré / signalé. Cela peut être assez compliqué, mais cela fait immédiatement apparaître des goulots d'étranglement.

Enfin, je collecte également des statistiques en masse, par exemple pour chaque appel mutex / signal / MPI, quels étaient les temps d'attente moyen et maximum? Quel est l'histogramme des temps d'attente collectés? Bien que l'intrigue vous donne un bon aperçu, il peut devenir assez compliqué quand il s'agit des détails les plus fins.

Enfin, une question à ne pas sous-estimer: comment recueillez-vous vos horaires? Votre temporisateur est-il suffisamment non intrusif pour ne pas influencer votre code? J'utilise le nombre d'instructions CPU autant que possible, c'est- RDTSCà- dire sur les architectures x86. Cela ajoute généralement une seule instruction à votre code.

Pedro
la source
Les données ont déjà des blocs autour de toutes les attentes; dans le diagramme, ils apparaissent en blanc pour les fils de travail inactifs et en jaune pour les fils de communication en attente. Malheureusement, toutes les attentes dans le thread de communication se produisent dans une seule couverture MPI_Waitsome en raison de l'asynchronie. Vtune ne s'applique pas dans ce cas car les performances purement threadées sont essentiellement parfaites, mais merci pour le pointeur. La suggestion d'histogramme est également bonne.
Geoffrey Irving
En ce qui concerne le temps système: j'utilise gettimeofday, qui est nécessaire au moins autour des sections inactives car là j'utilise des variables de condition pthread. Le nombre d'instructions CPU peut-il être fait pour fonctionner dans une telle situation? Les frais généraux sont déjà suffisamment bas, mais plus bas serait certainement plus agréable.
Geoffrey Irving
1
@GeoffreyIrving: Oui, vous pouvez les utiliser, mais elles n'ont de sens que sur les processeurs qui ont l' constant_tscindicateur défini (vérifier /proc/cpuinfo) et si vous utilisez verrouiller chaque thread sur un noyau spécifique, c'est-à-dire que chaque thread lit toujours le même registre à partir du même noyau, par exemple en utilisant pthread_setaffinity_np. Notez que ce dernier est spécifique à Linux et donc pas portable.
Pedro
@GeoffreyIrving: Même si vous attendez un événement non divulgué à l'aide MPI_Waitsome, vous pouvez toujours enregistrer les demandes qui sont réellement arrivées et d'où. Ces informations peuvent ou non être utiles ...
Pedro
5

Parfois, vous pouvez obtenir une vue alternative sur les problèmes de performances via une analyse de ressources de haut niveau: existe-t-il un goulot d'étranglement pertinent tel que la bande passante mémoire? Chaque thread de travail fait-il la même quantité de travail? Ces données peuvent être facilement collectées avec likwid-perfctr à partir de la suite d'outils LIKWID LIKWID projet de code Google . Si le profil est tel qu'il existe de nombreux points chauds différents, vous devrez peut-être les résoudre un par un. Il peut également y avoir différents problèmes, selon le nombre de threads / processus utilisés.

Georg Hager
la source
Dans un souci de parfaite divulgation, Georg travaille sur le projet LIKWID et j'ai sollicité cette réponse parce que je voulais compléter la grande réponse de Pedro avec une autre perspective (et un excellent outil disponible gratuitement).
Aron Ahmadia
2

Lorsque j'ai un problème dans un réseau de processus hautement asynchrones régis par des messages ou des événements, j'utilise une méthode qui n'est pas simple mais efficace. Cela impliquait d'obtenir des journaux horodatés des processus, de les fusionner dans une chronologie commune et de suivre la progression de certains messages lorsqu'ils déclenchent des activités, déclenchant d'autres messages. Ce que je recherche, c'est un délai entre le moment où un message est reçu et le moment où il est appliqué, et comprendre la raison du retard. Lorsqu'un problème est détecté, il est résolu et le processus est répété. De cette façon, vous pouvez obtenir des performances vraiment satisfaisantes.

Il est important de voir en quoi cela diffère des approches où vous mesurez, mesurez, mesurez. La seule chose que mesurer peut vous dire est de savoir où ne pas regarder. Le réglage des performances réelles nécessite une attention particulière aux détails, dans une perspective temporelle. Ce que vous cherchez, ce n'est pas où le temps est passé, mais où il est dépensé inutilement.

Bonne chance.

Mike Dunlavey
la source
En d'autres termes, il n'y a pas de visualisation utile des données dont je dispose. :) Jed Brown a suggéré Jumpshot (et les utilitaires associés) comme un moyen de collecter et de visualiser les données que vous suggérez, donc je vais examiner cela.
Geoffrey Irving du
@Geof: Bonne chance avec la visualisation. Le seul outil que j'aurais trouvé utile est de collecter et de fusionner les journaux des événements afin que je puisse suivre le chemin d'une ou plusieurs demandes au fur et à mesure de son chemin à travers les différents threads, car c'est la seule façon à ma connaissance de détecter les inutiles retards. Voilà en quoi consiste tout problème de performances - des retards inutiles.
Mike Dunlavey