<  Retour au portail Polytechnique Montréal

Débogage et traçage de processeurs à grand nombre de coeurs

Simon Marchi

Mémoire de maîtrise (2014)

Document en libre accès dans PolyPublie
[img]
Affichage préliminaire
Libre accès au plein texte de ce document
Conditions d'utilisation: Tous droits réservés
Télécharger (590kB)
Afficher le résumé
Cacher le résumé

Résumé

Les systèmes informatiques ont atteint un point où la performance d'un seul cœur rapide ou même d'un seul hôte puissant ne peut pas répondre à la demande. Les nouveaux systèmes sont donc de plus en plus bâtis selon des architectures distribuées, permettant une meilleure mise à l'échelle. On constate également l'arrivée de processeurs à grand nombre de cœurs, qui exploitent le parallélisme de façon extrême plutôt que de compter sur la puissance individuelle de chaque cœur. Ces changements compliquent l'utilisation des outils d'analyse du comportement des programmes. Nous nous sommes penchés sur deux problèmes en particulier, soit le débogage des appels à distance et le traçage sur processeurs à grand nombre de cœurs. Au sein de systèmes distribués, un paradigme fréquemment utilisé est celui des appels de procédures à distance. Cette technique permet à un processus de faire exécuter une fonction dans un contexte différent, par exemple sur un hôte distant, plus adapté à accomplir la tâche voulue. Ainsi le fil d'exécution logique de l'application passe d'un hôte à l'autre, même si chaque hôte possède évidemment son propre fil d'exécution réel. Des bibliothèques spécialisées permettent même de cacher la complexité des appels distants et font en sorte qu'ils soient aussi simples à effectuer qu'un appel local. Toutefois, les débogueurs n'ont généralement pas connaissance de cette technique. Leur efficacité dans ce contexte en est donc réduite, puisqu'il est impossible de suivre le fil d'exécution logique lorsqu'il quitte l'hôte actuel. Il existe quelques exemples de débogueurs auxquels la possibilité de suivre des appels à distance a été ajoutée. Par contre, il s'agissait toujours d'une solution spécifique à une bibliothèque particulière d'appels à distance ou à une seule plate-forme. Nous proposons dans ce mémoire une méthode générique permettant d'ajouter aux débogueurs une connaissance des systèmes d'appels à distance. Nous avons effectué une implémentation de la solution à l'aide du débogueur GDB. GDB possède plusieurs fonctions intéressantes, comme la gestion de plusieurs processus débogués à la fois et est facilement extensible. La solution consiste à placer des points d'arrêt aux endroits dans le programme client qui correspondent à l'initiation d'un appel à distance. Une fois un de ces points d'arrêt atteint, on peut déterminer à quel endroit l'exécution devrait passer dans le serveur pour servir la requête d'appel à distance du client. Il est alors possible d'y placer un point d'arrêt, afin d'interrompre le programme et permettre à l'utilisateur de continuer le débogage à partir de ce point. Une stratégie équivalente est utilisée pour le retour de l'appel à distance. La solution doit bien sûr être adaptée à chaque bibliothèque spécifique d'appels à distance. Toutefois, comme le même modèle d'exécution se retrouve dans la plupart de ces bibliothèques, il est possible d'extraire une grande partie de la logique dans un module générique. La portion restante, spécifique à chaque bibliothèque, est donc très petite. Pour démontrer la flexibilité de la solution, le support de plusieurs bibliothèques été ajouté. Le deuxième volet de notre travail porte sur le traçage des processeurs à grand nombre de cœurs. Dans des cas où le débogage interactif est trop invasif, le traçage peut être utilisé pour recueillir de l'information sur l'exécution du programme. Le traçage est semblable à la journalisation, mais met une emphase particulière à minimiser l'impact sur la performance de l'application étudiée. Des points de traces sont préalablement insérés dans le programme. Lorsque l'exécution croise un de ces points, une information (nommée un évènement) est sauvegardée dans la trace, le fichier résultant. Dans un système multi-cœurs, chaque cœur possède son propre fil d'exécution et représente ainsi un générateur d'évènements. On comprend que plus le nombre de cœurs est élevé, plus le débit d'évènements généré a le potentiel d'être grand. Si ce débit est plus grand que ce que le traceur est capable d'enregistrer sur le médium supportant la trace, le traceur sera contraint de laisser tomber des évènements, ce qui donnera une trace incomplète. Le traceur LTTng, développé à l'origine au laboratoire DORSAL de l'École Polytechnique de Montréal, est reconnu pour tracer efficacement aussi bien le noyau que les applications sur Linux. D'importants efforts ont été mis lors de son développement pour s'assurer que sa performance reste satisfaisante sur des systèmes multi-cœurs. La première étape de ce volet a été le port de LTTng à deux nouvelles architectures, TILE-Gx de Tilera et Xeon Phi d'Intel. Dans le cas du processeur de Tilera, nos travaux ont été effectués sur un processeur comportant 36 cœurs alors que celui d'Intel en comportait 57. Étant une architecture jeune, le port à TILE-Gx a requis plusieurs correctifs autant au noyau de Linux qu'à LTTng. Le port au Xeon Phi a quant à lui été beaucoup plus direct. Nous nous sommes ensuite intéressés à la performance de LTTng sur deux processeurs particuliers. Pour chacun, nous avons choisi une application représentative du segment de marché visé par le produit. Pour le processeur de Tilera, il s'agit d'un nœud de cache distribué au sein d'un système d'infonuagique. Pour celui d'Intel, il s'agit d'une application de calcul scientifique. Plusieurs variations de traçage et d'exécution ont été étudiées. Notamment, nous comparons la sauvegarde locale et par réseau des données de traçage. En effet, comme l'espace disque est très restreint sur ce genre de plate-formes, l'enregistrement local des données est assez limité. Les résultats montrent que l'impact en performance de LTTng sur les applications tracées ne change pas (en proportion), même à des nombres de cœurs très grands. Toutefois, la sauvegarde par réseau reste un problème, puisque le médium n'est pas capable de supporter le débit de traçage généré dès que la charge est importante sur un nombre élevé de cœurs.

Abstract

Computer systems reached a point where the performance of a single fast core, or even a single powerful host can't reach the required performance for some large-scale applications. New systems are more and more built using distributed architectures, allowing better scaling. Many-core processors, which exploit massive parallelism, are also more and more common. These changes make standard software analysis tools harder to use. In this work, we tackle two particular problems, the debugging of remote procedure calls and application tracing on many-core processors. Remote procedure calling is a paradigm often used when building distributedapplications. It allows calling a function in a different context, for example on a distant host, which could be more apt to complete the given task. We can see it as if the logical execution flow of the program went from one host to another, even though each host has its own real execution flow. Some specialized libraries help hiding the complexity of remote calls and make them almost as easy to use as local calls. Unfortunately, debuggers are generally not aware of this technique. They are therefore less useful in this context, since it is impossible to follow the logical execution flow when it leaves the debugged host. There are some examples of debuggers that have been taught how to debug remote procedure calls, but they are always targeting a particular library or platform. In our work, we propose a generic method to add knowledge of remote procedure call libraries to debuggers. We implemented the solution using the GDB debugger, because it has many useful features, such as multiple process support, and is easily extensible through its Python API. The solution consists of placing breakpoints at spots in the client program that correspond to the start of a remote call. When one of those breakpoints is hit, we can determine at which point in the server the execution should go to serve the remote call request. It is therefore possible to place a breakpoint there, which will interrupt the execution and allow the user to continue debugging from there. An equivalent strategy is used for the return portion of the call. Obviously, the solution must be adapted to each specific remote procedure call library. However, since all these libraries are based on the same execution model, it is possible to extract most of the logic in a generic module. The remaining portion, specific to each library, is relatively small. To demonstrate the flexibility of the solution, support for a few of those libraries has been added. The second part of our work is about tracing of many-core systems. In cases where interactive debugging is too invasive, tracing can be used to collect information about the runtime of a program. Tracing is similar to logging, but its priority is to minimise its impact on the performance and behavior of the analyzed program. Tracepoints are added beforehand in the studied program. When execution reaches one of those points, a piece of information, an event, is saved in the trace, the resulting file. In a multi-core system, each core has its own execution thread, and therefore is an event source. The higher the number of cores, the higher can be the rate of generated events. If the rate of tracing data is greater than what the rate the medium on which the trace is recorded is able to write to, the tracer has no choice but to start dropping events, which will result in an incomplete trace. The LTTng tracer, developped initially at the DORSAL laboratory of the École Polytechnique de Montréal, is able to efficiently trace the Linux kernel as well as userspace applications. A lot of efforts have been made to ensure that it scales well on multi-core systems. The first step of this work has been to port LTTng to two new architectures, TILE-Gx from Tilera and Xeon Phi from Intel. In the case of Tilera, we worked with a 36 cores processor. For the Xeon Phi platform, we worked with a 57 cores processor. Being a less mature architecture, the port to TILE-Gx required more fixes in the Linux kernel and LTTng than the Xeon Phi port. We then looked at the performance of LTTng on those two processors. For each one of them, we chose a typical application of the market segment they target. For the Tilera processor, we chose a distributed cache node, as we can find in a cloud-computing application. For the Intel processor, we chose a scientific computing application. Multiple variations in tracing and execution mode have been tested. For example, we compared saving the trace data locally and through the network. As disk space is very limited on this kind of platform, saving data locally is very restrictive. Results show that the impact of LTTng on the traced applications stays constant (in proportion), even with high number of cores. However, saving trace data through the network is a problem, since the medium is not able to cope with the data flow generated from intense work on a high number of cores.

Département: Département de génie informatique et génie logiciel
Programme: Génie informatique
Directeurs ou directrices: Michel Dagenais
URL de PolyPublie: https://publications.polymtl.ca/1416/
Université/École: École Polytechnique de Montréal
Date du dépôt: 23 juil. 2014 16:22
Dernière modification: 05 avr. 2024 22:33
Citer en APA 7: Marchi, S. (2014). Débogage et traçage de processeurs à grand nombre de coeurs [Mémoire de maîtrise, École Polytechnique de Montréal]. PolyPublie. https://publications.polymtl.ca/1416/

Statistiques

Total des téléchargements à partir de PolyPublie

Téléchargements par année

Provenance des téléchargements

Actions réservées au personnel

Afficher document Afficher document