72 research outputs found

    Estimation par analyse statique de la bande-passante d'accélérateurs en synthèse de haut niveau sur FPGA

    Get PDF
    L’accélération par coprocesseur sur FPGA de portions d’algorithmes logiciels exécutés sur un CPU à usage général est une solution utilisée depuis longtemps dans de nombreux systèmes embarqués lorsque le calcul à effectuer est trop complexe ou la quantité de données à traiter trop grande pour être réalisée par ce processeur trop général pour les contraintes de performance et de puissance données. Avec la fin de la loi de Moore, c’est également une option de plus en plus utilisée dans les centres de données pour pallier à la croissance exponentielle de la consommation de courant des approches CPU et GPGPU. De plus, la réalisation de ces coprocesseurs, bien que restant une tâche plus complexe que la simple programmation d’un processeur, est énormément facilitée par la démocratisation des logiciels de synthèse de haut niveau (HLS), qui permettent la transformation automatisée de code écrit en langages logiciels (généralement un sous-ensemble statique du C/C++) vers des langages de description matérielle synthétisables (VHDL/Verilog). Bien qu’il soit souvent nécessaire d’apporter des modifications au code source pour obtenir de bons résultats, les outils de synthèse de haut niveau comportent généralement un estimateur de performance rapide de la micro-architecture développée, ce qui facilite un flot de développement itératif. Cependant, en pratique, le potentiel de parallélisme et de concurrence des accélérateurs sur FPGA est souvent limité par la bande-passante vers la mémoire contenant les données à traiter ou par la latence des communications entre l’accélérateur et le processeur général qui le contrôle. De plus, l’estimation de cette bande-passante est un problème plus complexe qu’il ne paraît du premier coup d’œil, dépendant notamment de la taille et de la séquentialité des accès, du nombre d’accès simultanés, de la fréquence des différentes composantes du système, etc. Cette bande-passante varie également d’une configuration de contrôleur mémoire à une autre et le tout se complexifie avec les FPGA-SoC (SoC incluant processeurs physiques et partie logique programmable), qui comportent plusieurs chemins des données fixes différents vers leur partie FPGA. Finalement, dans la majorité des cas, la bande-passante atteignable est plus faible que le maximum théorique fourni avec la documentation du fabricant. Cette problématique fait en sorte que bien que les outils existants permettent d’estimer facilement la performance du coprocesseur isolé, cette estimation ne peut être fiable sans considérer comment il est connecté au système mémoire. Les seuls moyens d’avoir des métriques de performance fiables sont donc la simulation ou la synthèse et exécution du système complet. Cependant, alors que l’estimation de performance du coprocesseur isolé ne prend que quelques secondes, la simulation ou la synthèse augmente ce délai à quelques dizaines de minutes, ce qui augmente le temps de mise en marché ou mène à l’utilisation de solutions sous-optimales faute de temps de développement.----------ABSTRACT: FPGA acceleration of portions of code otherwise executed on a general purpose processor is a well known and frequently used solution for speeding up the execution of complex and data-heavy algorithms. This has been the case for around two decades in embedded systems, where power constraints limit the usefulness of inefficient general purpose solutions. However, with the end of Dennard scaling and Moore’s law, FPGA acceleration is also increasingly used in datacenters, where traditional CPU and GPGPU approaches are limited by the always increasing current consumption required by many modern applications such as big data and machine learning. Furthermore, the design of FPGA coprocessors, while still more complex than writing software, is facilitated by the recent democratization of High-Level Synthesis (HLS) tools, which allow the automated translation of high-level software to a hardware description (VHDL/Verilog) equivalent. While it is still generally necessary to modify the high-level code in order to produce good results, HLS tools usually ship with a fast performance estimator of the resulting micro-architecture, allowing for fast iterative development methodologies. However, while FPGAs have great potential for parallelism and concurrence, in practice they are often limited by memory bandwidth and/or by the communications latency between the coprocessor and the general purpose CPU controlling it. In addition, estimating this memory bandwidth is much more complex than it can appear at first glance, since it depends on the size of the data transfer, the order of the accesses, the number of simultaneous accesses to memory, the width of the accessed data, the clock speed of both the FPGA and the memory, etc. This bandwidth also differs from one memory controller configuration to the other, and then everything is made more complex when SoC-FPGAs (SoCs including a hard processor and programmable logic) come into play, since they contain multiple different datapaths between the programmable logic and the hard memory controller. Finally, this bandwidth is almost always different (and smaller) than the maximum theoretical bandwidth given by the manufacturer’s documentation. Thus, while existing HLS tools can easily estimate the coprocessor’s performance if it is isolated from the rest of the system, they do not take into account how this performance is affected by the achievable memory bandwidth. This makes the simulation of the whole system or its synthesis-then-execution the only trustworthy ways to get a good performance estimation. However, while the HLS tool’s performance estimation runtime is a matter of a few seconds, simulation or synthesis takes tens of minutes, which considerably slows down iterative development flows. This increased delay increases time-to-market and can lead to suboptimal solutions due to the extra development time needed

    Optimisation multi-niveau d'une application de traitement d'images sur machines parallèles

    Get PDF
    Cette thèse vise à définir une méthodologie de mise en œuvre d applications performantes sur les processeurs embarqués du futur. Ces architectures nécessitent notamment d exploiter au mieux les différents niveaux de parallélisme (grain fin, gros grain) et de gérer les communications et les accès à la mémoire. Pour étudier cette méthodologie, nous avons utilisé un processeur cible représentatif de ces architectures émergentes, le processeur CELL. Le détecteurde points d intérêt de Harris est un exemple de traitement régulier nécessitant des unités de calcul intensif. En étudiant plusieurs schémas de mise en oeuvre sur le processeur CELL, nous avons ainsi pu mettre en évidence des méthodes d optimisation des calculs en adaptant les programmes aux unités spécifiques de traitement SIMD du processeur CELL. L utilisation efficace de la mémoire nécessite par ailleurs, à la fois une bonne exploitation des transferts et un arrangement optimal des données en mémoire. Nous avons développé un outil d abstraction permettant de simplifier et d automatiser les transferts et la synchronisation, CELL MPI. Cette expertise nous a permis de développer une méthodologie permettant de simplifier la mise en oeuvre parallèle optimisée de ces algorithmes. Nous avons ainsi conçu un outil de programmation parallèle à base de squelettes algorithmiques : SKELL BE. Ce modèle de programmation propose une solution originale de génération d applications à base de métaprogrammation. Il permet, de manière automatisée, d obtenir de très bonnes performances et de permettre une utilisation efficace de l architecture, comme le montre la comparaison pour un ensemble de programmes test avec plusieurs autres outils dédiés à ce processeur.This thesis aims to define a design methodology for high performance applications on future embedded processors. These architectures require an efficient usage of their different level of parallelism (fine-grain, coarse-grain), and a good handling of the inter-processor communications and memory accesses. In order to study this methodology, we have used a target processor which represents this type of emerging architectures, the Cell BE processor.We have also chosen a low level image processing application, the Harris points of interest detector, which is representative of a typical low level image processing application that is highly parallel. We have studied several parallelisation schemes of this application and we could establish different optimisation techniques by adapting the software to the specific SIMD units of the Cell processor. We have also developped a library named CELL MPI that allows efficient communication and synchronisation over the processing elements, using a simplified and implicit programming interface. This work allowed us to develop a methodology that simplifies the design of a parallel algorithm on the Cell processor.We have designed a parallel programming tool named SKELL BE which is based on algorithmic skeletons. This programming model providesan original solution of a meta-programming based code generator. Using SKELL BE, we can obtain very high performances applications that uses the Cell architecture efficiently when compared to other tools that exist on the market.PARIS11-SCD-Bib. électronique (914719901) / SudocSudocFranceF

    Nouvelle architecture pour les environnements de développement intégré et traçage de logiciel

    Get PDF
    La conception et le développement de logiciels requièrent souvent l’utilisation d’un Environnement de Développement Intégré (EDI) pour assister et faciliter le travail des développeurs. Les EDI offrent, à travers une interface graphique, des outils pour l’édition, la compilation et le débogage du code. Cependant, lorsque ces outils ne sont pas adaptés et suffisants pour la détection de défauts de performance sur des logiciels complexes, comme les systèmes distribués, les développeurs se tournent vers des techniques de traçage. Des logiciels appelés traceurs récoltent des informations précises pendant l’exécution du système instrumenté, et les regroupent dans une trace. Une trace peut contenir une quantité importante de données. Des outils spécialisés ont été développés afin d’en automatiser le processus d’analyse et de visualisation. Au fur et à mesure qu’un logiciel grandit et se complexifie, l’utilisation de ces outils d’analyse et de visualisation devient tout aussi importante qu’un débogueur. Néanmoins, ces outils sont complexes, autonomes et difficilement réutilisables dans d’autres systèmes. De plus, ils ne supportent pas les mêmes analyses, les mêmes formats de trace, ni les mêmes cas d’utilisation, ce qui implique que le développeur ait besoin d’installer plusieurs outils pour arriver à ses fins. Dans le cadre de ce projet, nous cherchons donc à résoudre ces problèmes et à intégrer l’analyse et la visualisation de trace non seulement dans les EDI, mais dans tout autre système qui pourrait en bénéficier, tels que les serveurs d’intégration continue ou encore les systèmes de monitorage. Par conséquent, nous proposons une nouvelle architecture logicielle flexible basée sur une approche client-serveur, d’architecture orientée service et multicouche. Notre travail s’étend à l’implémentation de l’architecture du serveur au sein du projet Trace Compass et l’implémentation de l’architecture du client au sein d’un nouveau projet appelé TraceScape. Toutes nos contributions sont disponibles à code source ouvert. Des tests de performance ont été menés afin d’évaluer le surcoût associé à la nouvelle architecture par rapport à la précédente approche, et les résultats indiquent un surcoût acceptable.----------ABSTRACT: Creating software often requires using an Integrated Development Environment (IDE) to help and facilitate the development work. With a simplified user interface, IDEs provide many useful tools such as a code editor, a compiler, and a debugger. Nonetheless, when those tools are not enough to detect performance defects in a large, complex and multithreaded system, developers use tracing techniques. A program called tracer collects accurate information during the execution of an instrumented system. A trace could contain a lot of data, and specialized tools have been developed to analyze traces automatically and show the results in interactive views. As the software grows and becomes more complex, using trace visualization tools must be part of the developer tool environment, like the debugger in the software development process. However, trace visualization tools are sophisticated, standalone and hardly reusable in other systems such as an IDE. Moreover, they have their specific trace format support, specific use cases, and specific trace analyses. Most of the time, developers need to install and use several such tools to fulfill their needs. In this research project, we aim to solve those problems and integrate trace analysis and visualization in tools such as IDEs, monitoring systems or continuous integration systems. Thus, we propose a flexible software architecture based on client-server, service-oriented architecture and layered approaches. We implemented the server architecture in the Trace Compass project and the client architecture in a new project called TraceScape. All of our contributions are available online in open source repositories. We also evaluated our proposed architecture through benchmarks, and the results show that our approach has an acceptable overhead compared to the standalone approach

    Points de trace rapides et flexibles en X86

    Get PDF
    Le traçage est une technique très utile pour les développeurs afin de trouver les problèmes dans les systèmes complexes, et pour analyser l’exécution de ceux-ci. Le traçage permet d’enregistrer les informations de bas niveau d’un système avec un dérangement minimal de celui-ci. Ces informations présentent une vue d’ensemble de l’exécution du système sous test et permettent d’analyser son comportement. Plusieurs outils de traçage permettent à un développeur d’instrumenter un système en y ajoutant des appels d’enregistrement d’information. L’utilisation de ces outils n’est par contre pas toujours possible. En effet, il est nécessaire de recompiler et redéployer le système afin de modifier la définition des points de trace existants et d’en ajouter. Pour pallier à ce problème, des outils de traçage avec instrumentation dynamique peuvent être utilisés. Ceux-ci permettent l’ajout de traçage dans un programme, sans modification des exécutables concernés. Certains outils permettent aussi l’ajout d’instrumentation dans un processus en exécution avec un minimum de dérangement de celui-ci. Ainsi, il est possible pour un développeur d’instrumenter un programme déployé sans déranger l’exécution de celui-ci. La modification dynamique de processus en exécution est un procédé délicat qui demande une modification du code machine sans changement apparent à l’exécution de celui-ci. L’architecture multi-processeur des systèmes modernes pose un problème majeur pour la modification de processus en exécution : l’exécution d’opérations invalides durant la modification du processus. En effet, les fils d’exécution d’un système ne doivent pas être affectés durant la modification du code machine par un des fils. Plusieurs techniques peuvent être utilisées afin de modifier sans danger les programmes multi-fils en exécution.----------ABSTRACT: Tracing is a very useful technique used by developers in order to find problems in complex systems, and to analyze the execution of these systems. Tracing is the gathering of low level information about a system, disturbing said system as little as possible. A multitude of tracing tools enable a developer to instrument a system by adding tracepoints. The use of these tools is not always possible, however, since a recompilation and redeployment of the target system is necessary to modify existing tracepoints or add new ones. Indeed, in most cases, it is impossible to modify the tracing instrumentation of a running system. To resolve this problem, tracing tools with dynamic instrumentation can be used instead. These tools enable a user to add and modify the tracepoints of a running system, while affecting as little as possible the execution of this system. The dynamic modification of a running process is a delicate procedure that requires changing the machine code without affecting the execution of the process. The multi-core architecture of modern systems introduces a major hassle when trying to dynamically modify machine code: the execution of invalid instructions during the modification. Indeed, it is important that no thread be affected during the modification of a process. Multiple techniques can be used to safely modify running multi-threaded processes. First of all, stopping all threads of a process is an effective technique to insert a tracepoint into a running process. While a process is stopped, a tool can safely add instructions that branch to tracing code. This ensures that no thread is executing invalid instructions during the insertion. Every thread must be stopped to guarantee the safety of the insertion. It is not always possible to stop every thread in performance sensitive situations

    Composants multiplateformes pour la prise en compte de l'hétérogénéité des terminaux mobiles

    Get PDF
    In this thesis, we aim to decrease the development cost of applications for smartphones running Android, iOS, etc. Mobile applications are more and more complex. A few year ago, a mobile application was only design to display web content. Today, in addition, they are connected with the external world. For example, some applications are connected with watches, TVs, etc. Mobile applications became real softwares. However, in order to be visible by all smartphones users, mobile applications are designed, developed and deployed on every kind of smartphone. With the increase of the multiplicity of hardware configurations and the diversity of mobile operating systems, this task is becoming more and more laborious. Indeed, a mobile application is often implemented one time for each target platform (Android, iOS, Windows Phone 8, etc.). Therefore, the time and the cost for a mobile application implementation is multiplied by the number of target platforms. In this thesis, we propose to combine native development with the advantages of component-based software engineering. To do that, we have introduced the concept of multiplatform components. Those components are capable to be executed on any mobile platform. In order to describe components, we have introduced interfaces that are independent of any mobile platform. Thus, component integration and assembly are common on Android, iOS and others systems. To achieve that, we have specified a new programming language based on Annotations. We have validated this approach with the implementation of a real mobile application for Android and iOS. We have compared this application with the same application developed natively. Results show that with our solution, developers implement a multiplatform application 30% faster than native development. Moreover, our solution does not show any limitation for developers (same user experience, same performances). Finally, we have compared our solution with real products available on the software market: Phonegap, Titanium mobile and Xamarin. This comparison illustrates that our solution provides the best features and does not limit developers possibilities.Ces travaux de thèse visent à diminuer le coût de développement des applications mobilespour smartphones Android, iOS, etc. Les applications mobiles sont de plus en plus complexes. Auparavant, une application mobile se contentait d’afficher des données provenant du web. Maintenant, en plus de cela, elles communiquent avec le monde extérieur. Par exemple, certaines applications communiquent avec des montres, avec des écrans de télévision etc. D’autres permettent le scan de codes barres ou encore l’interaction avec des objets réels à travers la réalité augmentée. Les serveurs peuvent envoyer des notifications aux applications, etc. Une application mobile est devenue un logiciel à part entière. Cependant, pour toucher un maximum d’utilisateurs de smartphones, les applications mobiles doivent être conçues, implémentées et déployées sur tous les smartphones possibles. Avec la multiplication des configurations matérielles différentes ainsi que la multiplication des systèmes d’exploitation mobiles, cette tâche devient de plus en plus ardue. En effet, une application mobile doit souvent être réalisée une fois pour chaque plate-forme cible (Android, iOS, Windows Phone 8, etc.). Le temps et le coût de réalisation d’applications mobiles est donc multiplié par le nombre de plates-formes ciblées. Dans ces travaux, nous proposons de combiner le développement natif avec la programmation par composants. Pour ce faire, nous introduisons la notion de composants multiplateformes. Ce sont des composants qui peuvent être exécutés sur plusieurs plates-formes mobiles. Pour la représentation des composants, nous avons introduit la notion d’interface indépendante à n’importe quelle plate-forme mobile. Ainsi, l’intégration et l’assemblage se font d’une façon unique, que l’on soit dans un environnement de développement Android, iOS ou autre. Pour ce faire, nous avons spécifié un nouveau langage de programmation basé sur les annotations. Cette approche a été validée à travers le développement d’une application mobile pour Android et iOS avec notre solution. L’application implémentée a été réalisée en concordance avec les problématiques que rencontrent les entreprises de développement mobile et plus particulièrement Keyneosoft. Ensuite, nous avons comparé ces versions de l’application avec les versions développées nativement. Nous avons montré qu’avec notre solution nous diminuons le temps de développement d’au moins 30% sans aucune limitation pour les développeurs d’applications (même expérience utilisateur, même performance). Nous avons aussi comparé notre solution avec des produits disponibles sur le marché Phonegap, Titanium mobile et Xamarin. Nous en avons conclu que notre solutiton offrait le plus de possibilités sans aucune limitation

    Débogage à large échelle sur des systèmes hétérogènes parallèles

    Get PDF
    Le traitement parallèle est devenu une nécessité afin de bénéficier du plein potentiel des processeurs centraux modernes. En effet, l’ajout de coeurs de calcul est un des facteurs ayant eu le plus d’impact sur le gain de performance des processeurs dans les dernières années. Pour cette raison, l’usage des processeurs multicoeurs est de plus en plus répandu en industrie ainsi que chez les particuliers, et le nombre de coeurs continue à augmenter. Cependant, le développement de programmes adaptés aux processeurs parallèles apporte de nouveaux défis. En effet, le paradigme de développement séquentiel ne suffit plus, et le programmeur doit prendre en compte le parallélisme. Il doit s’assurer que les interactions entre les fils d’exécution ne créent pas de problèmes. Cela est difficile, notamment lorsque le programme utilise un grand nombre de fils d’exécution, et des problèmes dus au parallélisme peuvent survenir. Cela pose un défi important en industrie, car ces problèmes compliquent le développement logiciel, et peuvent augmenter les coûts de développement. Il est donc nécessaire d’avoir des outils adaptés au développement de programmes parallèles pour permettre aux programmeurs d’identifier et de trouver rapidement ces problèmes. Un outil vital pour le processus de développement logiciel est le débogueur. Cet outil permet à l’utilisateur de contrôler le fonctionnement d’un programme, de l’arrêter à certains endroits et d’utiliser plusieurs autres techniques pour trouver l’origine de problèmes. Or, la majorité des débogueurs et des techniques de débogage utilisés existent depuis plusieurs années, et ont été développés alors que les processeurs parallèles étaient peu répandus. Plusieurs problèmes liés au parallélisme découlent d’une mauvaise synchronisation entre les fils d’exécution. La course de donnée en est un exemple. Elle survient lorsque plusieurs fils d’exécution modifient une variable en mémoire sans synchronisation. La valeur finale de la variable dépend alors de l’ordre d’exécution des fils et peut varier entre différentes exécutions du programme. Ce type de problème n’est donc pas déterministe, et n’arrive pas nécessairement même si on ré-exécute un programme avec les mêmes valeurs de départ. Or, la plupart des techniques de débogage sont intrusives. En effet, stopper un programme et examiner ses variables a un effet important sur la synchronisation. Il arrive donc qu’un problème disparaisse ou change lorsqu’un programme est débogué en raison de l’impact du débogueur. Il est évident que des techniques de débogage minimalement intrusives sont nécessaires afin d’aider les développeurs à déceler ce type d’erreur. Un autre défi présent avec le débogage de programmes parallèles est l’interface utilisateur. En effet, les programmes parallèles contiennent un très grand nombre de fils d’exécution, et peuvent générer un grand débit d’évènements qui doivent être traités par le développeur. Par exemple, il peut être nécessaire d’inspecter l’état de plusieurs dizaines de fils d’exécution lors d’un arrêt du programme pour bien comprendre le contexte. Cela est une tâche pénible, et peut mener le développeur à manquer certains problèmes en raison d’une surcharge d’information. Il peut arriver qu’il soit difficile de trouver l’information pertinente à travers toutes les informations affichées. Il faut donc que l’utilisateur ait accès à une interface qui lui permette de facilement visualiser et contrôler l’état d’un programme.----------ABSTRACT : A significant proportion of performance gains in processors in recent years has come from parallel processing. Indeed, adding cores in a processor has been heavily used by most manufacturers to gain performance improvements. For this reason, multi-core and many-core processors are increasingly common in personal computers and industrial systems. However, designing software for parallel processors is not an easy task. Indeed, the sequential programming paradigm traditionally used is not sufficient anymore, as multiple tasks can be processed simultaneously. The software designer must take interactions between threads into account, and write code accordingly. This is a complicated task, especially when a program uses a large number of threads. This can lead to multiple issues, thus increasing development time and cost. Therefore, using development tools suitable for parallel development is essential to allow developers to quickly identify and locate these issues. One of the most important tools is the debugger, a tool to control a program execution and inspect its state. Unfortunately, most debugging tools have been in use for a long time, and were designed to debug single-threaded applications. Many problems can be created by a mistake in thread synchronization. One example is a data race, which occurs when multiple threads try to access a shared variable without concurrency control. In this case, its final value depends on the order in which each thread accesses it, and the result may change between different executions as the thread scheduling varies. Inspecting this type of problem with a debugger can be problematic, as a debugger can be very intrusive and disturb the execution of the program. Therefore, a multi-threading issue may be masked or modified during debugging, greatly diminishing the usefulness of the debugger. Thus, adapted debugging techniques are needed for parallel software. Another challenge is the large amount of data to be handled by the user. Indeed, as parallel software may contain a great number of threads, there is a lot of information to display, and a large number of events can be generated. This can confuse the developer by overloading him with information. Therefore, appropriate techniques to visualize and control multi-threaded software are needed. These two challenges have been addressed during this research project. Two different platforms have been used for tests. The first one is a server with four multi-core processors that has a total of 64 physical cores. The other one is a general-purpose computer with a multi-core processor and a graphic card used for calculations. The GDB debugger has been enhanced to allow dynamic scalable tracing in order to trace parallel programs with minimal overhead. This enhancement has been achieved by modifying GDB to address limitations for parallel tracing, and using LTTng for trace collection. LTTng has also been enhanced to allow dynamic event registration. Finally, the impact of conditional breakpoints has been measured, and a technique to minimize this impact has been proposed

    Intégration dans un flot de conception système d'un outil de traduction assistée de code C pour la création de coprocesseurs matériels

    Get PDF
    RÉSUMÉ Depuis les débuts de la conception de systèmes électroniques, un des buts de la recherche est de fournir des outils et méthodes de travail de plus en plus puissants et rapides. Ceci est illustré très explicitement dans le fossé qui sépare la croissance du nombre de transistors par puce de la croissance du nombre de transistors intégrés par ingénieur par mois. Au cours des années se sont alors développées des méthodes permettant à un concepteur d’abstraire de plus en plus son travail afin de faciliter l’intégration et la distribution de composantes matérielles. À ces abstractions de description viennent s’ajouter des outils automatisant certaines parties du travail d’un concepteur. C’est par exemple le cas de la synthèse haut-niveau, qui permet de synthétiser des algorithmes de manière guidée. Enfin, de nombreux flots de travail ont aussi vu le jour afin de fournir une méthodologie dans la conception de systèmes électroniques. Le flot que nous retiendrons est le flot niveau système électronique (ESL) qui décrit une méthode de développement incrémentale partant d’une description la plus abstraite possible. Les abstractions sont itérativement relâchées pour finalement arriver à une description matérielle. Toutefois, il n’existe pas d’outil complet intégrant toutes les étapes du flot ESL. Nous proposons donc un outil de traduction assistée de code C afin de compléter un flot de conception ESL dans le cadre de la création de coprocesseurs matériels. L’outil proposé, C2Space, permet la transition d’un code C séquentiel vers un code organisé en modules SpaceStudio de manière rapide et configurable. Cet outil de traduction, basé sur le transpilateur Clang, procède à l’analyse statique du code pour effectuer les choix de traduction appropriés. C2Space permet l’intégration en amont du flot d’une solution d’analyse dynamique de code C, appelée Pareon Profile. Pareon permet une première analyse du code séquentiel afin de repérer rapidement les portions du code susceptibles de profiter d’un passage sur coprocesseur (de par leur potentiel de parallélisme et leur poids dans l’exécution séquentielle). Une fois la traduction effectuée, le reste du flot est supporté par l’environnement de codéveloppement SpaceStudio, qui permet alors de procéder à l’exploration architecturale du code traduit. Il est alors possible de tester différents schémas d’allocation des modules aux ressources matérielles (processeurs, coprocesseurs). Les modules alloués en matériel sont alors synthétisés à l’aide d’un logiciel de synthèse haut-niveau. Le système complet peut ensuite être exporté vers une des plateformes matérielles supportées (par exemple, pour FPGA Xilinx). Nous avons confronté ce flot à un algorithme de détection de contours (filtre de Canny) afin d’en tester l’efficacité. Les résultats montrent que l’approche proposée permet un raffinement rapide de l’algorithme, de sa définition logique jusqu’à son implémentation. Nous n’avons pu accélérer, comme envisagé initialement, la vitesse d’exécution de l’algorithme, mais nous avançons plusieurs pistes pour expliquer ces résultats. Nous proposons une série de recommandations visant à améliorer à la fois C2Space et le flot proposé. Nous décrivons notamment l’utilisation d’une nouvelle métrique très tôt dans le flot de conception mettant en relation (1) le potentiel de parallélisme d’un segment de code, (2) la portion du temps d’exécution global de ce segment, (3) le coût de communications processeur/coprocesseur pour ce segment et (4) le temps d’exécution logiciel de cette même portion de code.----------ABSTRACT Since the beginning of Electronic System Design, one of the main goals pursued in research has been to provide smarter and faster tools and workflows. This is clearly shown in the gap that separates the number of transistor per chip and the number of transistor that can be integrated by an engineer in a month. Over the years, many methods allowing a designer to abstract more and more his design came to fruition. In addition to those methods, automatization of certain tedious and repetitive tasks in the design process appeared. For instance, the tools of High Level Synthesis allow a high level specification to be automatically translated into a working Register Transfer level design. Finally, numerous workflows arose to provide more definite framework in Electronic System Design. The workflow that we will tackle is the Electronic System Level Flow (ESL), which describe an incremental method that starts from the most abstract specification possible. Abstraction is then released in small increments until a fully hardware specification is obtained. However, there is no comprehensive tool incorporating all stages of the ESL flow. We therefore propose an assisted translation tool for C code in order to complete an ESL design flow as part of creating hardware coprocessors. The proposed tool, C2Space, allows the transition of a sequential C code to a code organized in SpaceStudio modules in a fast and configurable way. This translation tool, based on the transpiler Clang, performs static analysis of the code to perform the appropriate translation choices. C2Space allows the integration, upstream of the flow, of a dynamic code analysis solution for C, called Pareon Profile. Pareon allows a first analysis of the sequential code to quickly identify sections of code that could benefit from a passage on coprocessor (by their potential parallelism and their weight in the sequential execution). Once the translation is done, the rest of the workflow is supported by the co-design environment SpaceStudio, which allows for architectural exploration of the translated code. It is then possible to test different mappings of the modules to the hardware resources (processors, coprocessors). Modules that are allocated material are then synthesized using a high-level synthesis software. The complete system can then be exported to one of the supported hardware platforms (e.g., for Xilinx FPGAs). We compared this flow to an edge detection algorithm (Canny filter) to test its effectiveness. The results show that the proposed approach enables rapid refinement of the algorithm, from the logic definition to its implementation. We have not been able to accelerate, as originally envisioned, the execution speed of the algorithm but we are offering several possible explanations for these results. We provide a series of recommendations to improve both C2Space and the proposed workflow. We describe in particular the use of a new metric early in the design flow linking (1) the potential parallelism of a code segment, (2) the portion of the total execution time of this segment, (3) the cost of communications between processor and coprocessors for this segment and (4) the software runtime of that same piece of code)

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

    Get PDF
    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

    Traçage noyau et distribué d’applications réparties pour l’analyse de la performance

    Get PDF
    L’essor de l’infonuagique s’est accompagné de la transition depuis les applications monolithiques, lourdes et complexes à maintenir, vers les applications réparties sous forme de services flexibles et performants. Grâce à l’amélioration des outils de déploiement et de mise à l’échelle, ces dernières ont une efficacité accrue, une meilleure résistance aux pannes ainsi qu’un meilleur découpage sous forme de services développés indépendamment. Toutefois, les applications réparties présentent des difficultés nouvelles liées à leur transparence de fonctionnement et à leur débogage. Une simple requête peut donner lieu à des dizaines de sous-requêtes interdépendantes et traitées par des machines physiques différentes. Le traçage distribué permet partiellement de répondre au problème en fournissant à l’utilisateur une vue en cascade de chaque requête au complet, incluant les durées de chaque sous-requête. C’est une technique précieuse qui permet d’identifier rapidement des requêtes défaillantes et des services anormalement lents. En revanche, et alors même que les applications ciblées sont conçues pour exécuter plusieurs requêtes en parallèle, le traçage distribué ne permet pas d’expliquer les causes d’une latence lorsque celle-ci découle d’une contention entre services ou entre requêtes concurrentes. L’objectif de ce projet de recherche est d’étendre le traçage distribué à l’analyse de cause racine appliquée à des problèmes de contention. Notre hypothèse de travail est que, grâce à l’ajout d’événements de bas niveau issus de traces noyau, il est possible de créer des algorithmes permettant à l’utilisateur de comprendre la cause d’une latence observée dans une application distribuée. Nous proposons à cette fin de combiner le traçage distribué avec le traçage logiciel, de la collecte des événements à leur analyse ultérieure.----------ABSTRACT: Cloud applications have transitioned from centralized to distributed architectures deployed as smaller services. Tools for deploying and scaling distributed applications have made them more flexible, more efficient, more resilient and easier to maintain than their monolithic counterparts. However, distributed applications are also more difficult to analyze and debug. Indeed, a single user request can trigger tens of subrequests than span across multiple services and physical machines. Distributed tracing partially addresses this problem by providing the user with the complete flow of a given request and the duration of each of its subrequests. While it is very useful for identifying faults and slow services, it fails at explaining the root cause when it is related to contention between services or requests. This is even more critical since distributed applications are often built for concurrency. The objective of this research project is to extend distributed tracing to the root cause analysis of contention in distributed applications. Our assumption is that we can include low-level kernel events to trace analyses to better understand the cause of detected latency. To that end, we propose combining distributed tracing with kernel tracing, from collecting to analyzing the events. We designed a technique for collecting and synchronizing high-level distributed tracing events and low-level kernel events altogether. Our solution is based on instrumenting a distributed tracer with a software tracer that operates in user space. We used Jaeger as a distributed tracer and LTTng as a software tracer for our implementation. We showed that the performance impact of our solution could be controlled by lowering the sampling frequency of tracing in the target application

    Conception d'un outil de modélisation intégré pour l'indexation et l'analyse de trace

    Get PDF
    RÉSUMÉ Les simulateurs de vol sont des systèmes composés d'un système logiciel et d'actuateurs mécaniques qui recréés la dynamique d'un vrai vol avec un aéronef et qui sont notamment utilisés par les compagnies de transport aérien pour former leurs futurs pilotes. Ces simulateurs doivent recréer des scénarios de vol permettant d'exécuter des itinéraires réguliers de vol ou de confronter les pilotes à différentes situations d'urgence qui peuvent subvenir lors d'un vrai vol (p. ex., une tempête violente). Puisque les simulateurs de vol ont un impact direct sur la qualité de formation des pilotes, une batterie exhaustive de tests s'impose à chaque fois qu'une nouvelle version d'un simulateur doit être mise en opération. Une bonne partie de ces tests requièrent l'intervention d'un pilote qui stimule le système en réalisant une série d'opérations de contrôle provenant de scénarios de vol préparés par des experts en aéronautique, ce qui est gourmand en temps, en ressources humaines et en ressources financières. La raison de la nécessité de réaliser tous ces tests est que le logiciel en soit est constitué de plusieurs composants de type boîte noire dont le code source n'est pas disponible, ils sont fournis tels quels par les fournisseurs du composant réel d'origine devant être simulé (p. ex., un composant hydraulique d'un aéronef que nous voulons simuler). Puisque nous n'avons pas pas accès au code source, il n'est pas possible lors de la mise-à-jour de l'un de ces composants de savoir quel sera le changement dans le comportement du simulateur. Dans le meilleur des cas, un défaut dans un composant aura un impact local et, dans le pire des cas, il peut nuire à tous les autres composants du simulateur. Il est dans ce cas nécessaire d'utiliser une stratégie de test d'une large granularité couvrant à la fois le fonctionnement des composants eux-mêmes et l'ensemble des fonctionnalités de vol du simulateur afin d'en assurer sa qualité. Dans le cadre de ces tests, afin de réduire le temps requis pour vérifier le bon comportement d'une nouvelle version d'un simulateur, nous proposons dans ce mémoire d'automatiser l'analyse des résultats de test en modélisant le comportement normal du système logiciel en utilisant de l'apprentissage automatique. Un tel modèle tente de recréer le comportement stable du système en bâtissant des règles reliant ses entrées à chacune de ses sorties. Les entrées sont constituées de métriques provenant des contrôles qui stimulent le système et les sorties sont constituées de métriques que nous pouvons observer. Nous produisons donc un modèle initial d'une version fiable du simulateur et nous validons par la suite le bon comportement des versions subséquentes en comparant leur comportement avec celui du modèle initial. Nous cherchons à voir s'il y a un écart trop important avec le modèle initial, ce nous considérons comme étant une déviation. Le but final de notre recherche est de pouvoir appliquer notre méthodologie d'analyse des résultats de test dans l'industrie de la simulation. Afin d'avoir plus de flexibilité dans nos expérimentations, nous commençons d'abord par valider l'approche avec un simulateur plus simple et ouvert. Nous utilisons donc le simulateur de vol à source libre FlightGear comme cas d'étude pour évaluer notre approche de test. Ce simulateur utilise l'engin de vol très populaire JSBsim et la librairie SimGear pour modéliser les aéronefs et simuler leur comportement dynamique dans un environnement de vol. JSBsim est notamment utilisé par la Nasa à des fins de recherche. Nous réalisons d'abord un vol manuel en utilisant des périphériques de contrôle d'un ordinateur tout en enregistrant les données contenues dans le simulateur. Le vol doit être composé de toutes les opérations régulières de pilotage afin que le modèle que l'on en extrait représente fidèlement le comportement normal du simulateur. Nous réalisons par la suite plusieurs répétitions du même vol afin d'identifier des niveaux de seuils robustes pour déterminer au delà de quels écarts un métrique d'une nouvelle version doit être considéré comme déviant par rapport au modèle. Nous élaborons à cet effet cinq scénarios de mutation du comportement de la version initiale de notre simulateur afin de générer différentes versions ayant des métriques qui respectent le comportement normal du sytème ou présentant une déviation du comportement normal reliée à un problème fonctionnel. En sachant d'avance quelles mutations présentent des déviations et avec l'aide d'experts identifiant précisément les métriques qui dévient de leur comportement normal, nous pouvons construire un oracle avec lequel nous évaluons la précision et le rappel de notre approche de détection. En particulier, dans le cadre de notre étude empirique sur FlightGear, nous modifions une version initiale du simulateur en y injectant cinq différentes mutations qui n'ont pas d'impact grave ou qui engendrent des problème fonctionnels avec lesquels nous évaluons notre approche. Les résultats montrent qu'en choisissant des niveaux de seuil initiaux lors d'une première calibration, notre approche peut détecter les métriques ayant des déviations avec un rappel majoritairement de 100% (un seul cas de mutation à 50%) et une précision d'au moins 40%. En ce qui a trait aux mutations ne changeant pas le comportement normal du simulateur, notre approche a un taux de fausses alarmes de 60%. Nous montrons également qu'avec une base de données plus large, il est possible de calibrer notre approche afin d'améliorer sa performance. Avec des niveaux de seuil optimaux qui sont calibrés pour chacune des mutations, nous obtenons un taux de rappel de 100% pour tous les cas, une précision d'au moins 50% pour les versions ayant des problèmes fonctionnels et un taux de fausses alarmes de 0% pour les versions n'ayant pas de problèmes fonctionnels. Afin d'ouvrir la voie pour des améliorations futures, nous utilisons notre méthodologie pour faire une petite expérimentation connexe sur JSBsim afin de détecter les déviations dans les transitions entre les états stables de chacun des métriques. Nous utilisons la même modélisation du simulateur. Les résultats montrent que nous pouvons battre une classification aléatoire des déviations. Cette nouvelle approche n'en n'est qu'à ces débuts et nous sommes convaincu que nous pouvons obtenir des résultats plus significatifs avec de futurs travaux sur le sujet. Nous proposons également dans les améliorations futures de descendre le niveau de granularité de notre modélisation du simulateur au niveau de chacun de ses composants. Cela permettrait d'isoler exactement qu'elle composant présente une déviation, et ainsi trouver la source du problème.----------ABSTRACT Flight simulators are systems composed of software and mechanical actuators used to train crews for real flights. The software is emulating flight dynamics and control systems using components off-the-shelf developed by third parties. For each new version of these components, we do not know what parts of the system is impacted by the change and hence how the change would impact the behaviour of the entire simulator. Hence, given the safety critical nature of flight simulators, an exhaustive set of manual system tests must be performed by a professional pilot. Test experts then rely on the test pilot's feedback and on the analysis of output metrics to assess the correctness of a simulator's behaviour, which consumes time and money, even more these tests must be repeated each time one of the components is updated by its vendor. To automate the analysis of test results from new simulator versions, we propose a machine learning-based approach that first builds a model that mimics the normal behaviour of a simulator by creating rules between its input and output metrics, where input metrics are control data stimulating the system and output metrics are data used to assess the behaviour of the system. We then build a behavioural model of the last-known correctly behaving version of the simulator, to which we compare data from new versions to detect metric deviations. The goal of our research is to first build a model of the simulator, then detect deviations of new simulator versions using that model, and finally develop an automatic approach to flag deviations when there are functional problems Our case study uses the open-source flight simulator Flight Gear, based on the well-known JSBsim flight dynamic engine currently used by the Nasa. Applying our approach, we first drive a manual basic flight using computer peripherals while recording metrics in the simulator. We then use the recorded metrics to build a model of this basic execution scenario. After repeating several times our flight we have enough data to identify robust metric deviation thresholds to determine when a metric in a new version is deviating too far from the model. We generate five different versions of FlightGear by injecting harmless and harmful modifications into the the simulator, then perform again our initial flight multiple times for each of those versions while recording input and output metrics. We rely on experts identifying which output metric should be deviating in each scenario to build an oracle. Using an initial threshold, our approach can detect most of the deviations in problematic versions with a near perfect recall (only one case at 50%) and a reasonable precision of at least 40%. For the versions without harmfull deviations we get a false alarm rate of 60%. By optimizing the threshold for each version, we get a perfect recall of 100%, a precision of at least 50%, and a false alarm rate of 0% for the good behaving versions. To open the path for future work, we perform a case study on JSBsim using a variant of our basic deviation detection approach to detect transient deviations using the same model. Our results show that we can beat a random classification for one kind of deviation, however for other deviations our models do not perform as well. This new approach is just a first step towards transient deviation detection, and we are convinced that we can get better results in future work. We also propose to use finer-grained models for each component to be able to isolate the exact component causing a functional problem
    • …
    corecore