Accélérateurs matériels spécialisés pour systèmes embarqués
Les tâches consommatrices de ressources de calcul (par exemple le décodage d’un flux H264) nécessitent plus qu’un processeur programmable pour respecter les contraintes de performance. En effet leur coût de production élevé ainsi que leur faible efficacité énergétique sont le prix à payer pour conserver la flexibilité d’un jeu d’instruction. Pour être compétitifs, les systèmes sur puce intègrent donc des accélérateurs spécialisés, dédiés à certaines tâches très consommatrices en ressources de calcul. Par exemple la plupart des Smartphones embarquent des décodeurs H264 implémentés sous forme d’accélérateurs spécialisés.
Ces accélérateurs spécialisés offrent une efficacité énergétique nettement supérieure à ce que proposent les processeurs à jeu d’instructions, allant jusqu’à trois ordres de grandeur [1]. Cette efficacité est cependant le résultat d’une étape de conception longue et fastidieuse, pendant laquelle une spécification algorithmique, décrite dans des langages de haut niveau (tels que C/C++), est traduite manuellement dans un langage de description matérielle, tel que VHDL (Very-high-speed integrated circuits Hardware Description Language) ou Verilog.
Flot de conception d’un accélérateur spécialisé
Le processus de conception se décompose principalement en deux étapes. la première consiste à traduire la spécification algorithmique en une description matérielle au niveau RTL (Register Transfert Level : Niveau de Transferts de signaux entre des Registres). La seconde étape, aujourd’hui systématiquement réalisée de manière automatique par les outils de synthèse logique, traduit la description matérielle en un réseau de portes ou transistors. Cette première étape est encore souvent réalisée manuellement par des experts. Elle ne consiste pas simplement en une traduction des algorithmes, mais aussi en une transformation de leurs spécifications, de manière à permettre une exécution parallèle, améliorer la localité des accès mémoire, ou réduire la complexité de certaines opérations. À l’heure actuelle la complexité des applications incite les concepteurs à utiliser des outils d’aide à la conception afin de respecter les délais de mise sur le marché.
Synthèse de haut niveau d’accélérateurs spécialisés
Ces outils d’aide à la conception opèrent directement sur des programmes C/C++, et produisent une description matérielle en Vhdl ou Verilog. Cette opération est appelée synthèse de haut niveau. Ces outils de HLS (High-Level Synthesis : Synthèse de Haut Niveau) permettent des gains de productivité importants (d’un facteur allant de 5 à 10 d’après les industriels), et sont aujourd’hui utilisés en production. Même s’ils offrent aux concepteurs la possibilité de choisir finement les caractéristiques de l’architecture générée, ces outils ont une efficacité qui dépend énormément de la façon dont les algorithmes en C/C++ sont spécifiés : ils sont bien souvent incapables de transformer efficacement les programmes pour exploiter parallélisme et localité.
La conception d’un accélérateur matériel spécialisé passe donc souvent par une étape d’exploration, réalisée en réécrivant le programme C/C++. L’objectif de cette exploration est de simplifier la tâche de l’outil de Hls et d’obtenir ainsi un accélérateur matériel plus performant.
Exploration de l’espace de conception
À partir d’une spécification à haut niveau, dans des langages tels que C/C++, il faut faire apparaitre du parallélisme de manière explicite et transformer les accès mémoire de manière à améliorer leur localité. Les outils de Hls proposent aux concepteurs des annotations, généralement sous la forme de #pragmas, pour ajouter cette sémantique absente dans les langages. On retrouve par exemple des annotations pour dérouller des boucles, qui vont permettre de vectoriser l’exécution du corps de la boucle ; indiquer à l’outil de Hls qu’une boucle doit être exécutée de manière pipelinée ; ou encore spécifier qu’un tableau doit être implanté dans des registres au lieu d’une mémoire.
La transformation de pipeline de boucle (loop pipeline ou software pipeline) est une transformation clé lors de la mise en œuvre matérielle d’une application. Le principe est de découper le corps de la boucle en n étapes, exécutées par n étages de pipeline (pipeline stages), chaque étape étant exécutée en un cycle, puis d’entrelacer l’exécution de n itérations du corps de la boucle à un instant donné . Cette transformation permet de diminuer significativement le temps d’exécution. Il faut cependant s’assurer au préalable qu’aucune dépendance n’est violée lors de l’application de cette transformation.
Compilation source-à-source pour la synthèse de haut niveau
Les industriels utilisent aujourd’hui ces outils de Hls en production. Cependant, les limitations de ces outils obligent les concepteurs à restructurer et annoter les programmes sources en C/C++. Dans le cadre du programme de recherche Nano2012, le projet S2S4HLS (SourceTo-Source For High-Level Synthesis : source-à-source pour la synthèse de haut niveau), soutenu par Inria et STMicroelectronics, vise à automatiser cette étape d’exploration en utilisant des transformations source-à-source .
Les compilateurs source-à-source génèrent du code dans le même langage que celui utilisé en entrée. Ils permettent d’appliquer des transformations de haut niveau tout en restant indépendants des outils de compilation ou de Hls utilisés en aval. Plusieurs outils (Pluto [2], Cetus [3], Rose [4]) ont déjà montré l’intérêt des compilateurs source-à-source dans le cadre de la parallélisation automatique pour machines parallèles. L’objectif de la compilation source-à-source, dans le cadre de la Hls, est de transformer le programme original pour faire apparaitre automatiquement des structures que l’outil de Hls peut facilement exploiter. Le projet S2S4HLS regroupe trois sous-projets, visant à :
– transformer les boucles pour faciliter une mise en œuvre matérielle performante;
– déterminer des tailles idéales pour les types à virgule fixe à partir d’une spécification en virgule flottante ;
– détecter des motifs dans les graphes de données, de manière à accélérer l’étape d’ordonnancement et utiliser des macro-opérateurs.
Amélioration de l’applicabilité du pipeline de nid de boucles
En utilisant la représentation des nids de boucles dans le modèle polyédrique, nous avons mis au point une technique d’analyse de la légalité du pipeline de nids de boucles. Cette technique permet, en trois temps :
– d’évaluer rapidement de manière imprécise (mais conservative) la légalité du pipeline de nid de boucle ;
– de vérifier précisément la légalité lorsque la première étape échoue ;
– de corriger un pipeline a priori illégal, en insérant des états d’attente.
De plus, en se basant sur la technique de génération de code polyédrique proposée par Boulet et Feautrier [5], il est possible de générer une boucle mise à plat qui facilite l’application du pipeline de nid de boucles par les outils de Hls. Pour les expérimentations et pour rester autant que possible indépendant des outils de Hls, nos méthodes ont été implémentées dans l’infrastructure de compilation source-à-source Gecos [6].
|
Table des matières
Introduction
1 Accélérateurs matériels spécialisés pour systèmes embarqués
1.1 Introduction
1.2 Applications et architectures embarquées
1.2.1 Quelques exemples d’applications embarquées
1.2.2 Critères de performance
1.2.3 Solutions architecturales
1.2.4 Contraintes économiques
1.3 Conception de systèmes embarqués
1.3.1 Description comportementale de l’application
1.3.2 Conception conjointe logicielle-matérielle
1.3.3 Conception d’accélérateurs matériels spécialisés
1.4 Conclusion
2 Synthèse de haut niveau d’accélérateurs spécialisés
2.1 Introduction
2.2 Synthèse d’accélérateur matériel à partir d’une description comportementale
2.2.1 Compilation de la description comportementale
2.2.2 Ordonnancement, allocation et placement
2.2.3 Génération de l’architecture
2.3 Optimisations pour une synthèse d’accélérateurs performants
2.3.1 Réduction de la complexité des calculs
2.3.2 Transformation des structures de données, des ressources de stockage et des accès à la mémoire
2.3.3 Exploitation du parallélisme
2.4 Conclusion
3 Modèle polyédrique et synthèse de haut niveau
3.1 Introduction
3.2 Flot global de transformation
3.2.1 Représentation des programmes dans le modèle polyédrique
3.2.2 Spécification et application des transformations
3.2.3 Génération de code
3.3 Légalité des transformations
3.3.1 Représentation des dépendances de données
3.3.2 Transformations des dépendances et condition de légalité
3.3.3 Analyse des dépendances de données
3.3.4 Extensions
3.4 Transformations automatiques
3.4.1 Le cas monodimensionnel
3.4.2 Le cas multidimensionnel
3.4.3 Transformations optimisantes
3.5 Application du modèle polyédrique à la Hls
3.5.1 Mmalpha
3.5.2 Réseau de processus polyédriques
3.5.3 Optimisation des accès mémoire
3.6 Conclusion
4 Génération de contrôle pour le modèle polyédrique
4.1 Introduction
4.2 Parcours de polyèdres
4.2.1 Problématique et approches basiques
4.2.2 Génération de nids de boucles efficaces
4.2.3 Génération d’une machine à états
4.3 Génération de contrôleur matériel
4.3.1 Cloogvhdl
4.3.2 Mmalpha
4.3.3 Réseau de processus polyédriques
4.3.4 Transformations source-à-source et outils de Hls
4.4 Amélioration de la génération de contrôle
4.4.1 Structure des boucles
4.4.2 Représentation des domaines et relations polyédriques
4.4.3 Réduction de force
4.4.4 Analyse de taille de type
4.5 Conclusion
Conclusion