L’hétérogénéité dans les systèmes de calcul
Les lois empiriques de Moore ont permis le développement des systèmes d’information qui occupent une place croissante dans notre société depuis l’invention du premier circuit intégré, en 1958, par Jack Kilby [66]. En 1965, Gordon E. Moore partageait [78] sa vision du futur de l’industrie de la microélectronique. À une époque où les systèmes de calcul sont pratiquement réservés à des usages militaires, ses propos se sont avérés particulièrement justes. En effet, il prédisait que les circuits intégrés permettraient l’avènement de l’ordinateur personnel, des voitures autonomes ou encore du téléphone portable. Mais, cet article est principalement connu comme étant l’établissement de la première loi de Moore. À ce moment, il prédisait que le nombre de transistors intégrés par circuit doublerait tous les ans et que le coût de fabrication par composant allait décroître pendant 10 ans. En 1974, Moore est invité à se prononcer à nouveau sur sa vision de l’évolution de l’industrie de la microélectronique [79]. Il corrige alors sa prédiction, en annonçant un doublement du nombre de transistors intégrés par circuit tous les deux ans. Ce postulat se révèlera particulièrement proche de la réalité et restera comme la loi de Moore.
La mise à l’échelle de Dennard est une observation partagée par Rober H. Dennard et al. [39] en 1974. Celle-ci conclut que grâce à la miniaturisation des transistors, il est possible d’augmenter leur densité d’intégration et la fréquence de fonctionnement des circuits sans accroître la consommation énergétique. Cette observation s’appuie sur le fait que la réduction de la taille des transistors permet de baisser leur tension d’alimentation et de raccourcir leur délai de commutation. David House, un employé de l’entreprise Intel, utilisa la loi de Moore et la mise à l’échelle de Dennard pour annoncer que la puissance de calcul des microprocesseurs doublerait tous les 18 mois. Cette prédiction (souvent associée à tort à la loi de Moore) se révéla juste pendant plusieurs années.
La perte de la mise à l’échelle de Dennard
Survenue dans les années 2000, explique le ralentissement de l’accroissement de la puissance de traitement des processeurs. Avant cette date, l’augmentation du nombre de transistors dans les puces permettait de concevoir des processeurs plus complexes et donc plus efficaces avec une seule unité de traitement, notamment grâce à des évolutions architecturales telles que : le pipeline d’instructions [4], l’exécution dans le désordre des opérations flottantes avec l’algorithme de Tomassulo [106], l’intégration d’une mémoire cache dans le processeur [54] ou encore la prédiction des branchements [97]. Cependant, l’augmentation des performances des processeurs était principalement soutenue par l’accélération de leur cadence d’horloge permise par la mise à l’échelle de Dennard. En atteignant des limites physiques, celle-ci a fortement ralenti. Les concepteurs de circuits intégrés ont du faire face à ce problème. En continuant d’augmenter la fréquence d’horloge des processeurs, la consommation énergétique allait croître. L’énergie consommée par un circuit est dissipée sous forme de chaleur. En dépassant un certain seuil, celle-ci peut endommager le circuit.
Les systèmes hétérogènes sont des systèmes de calcul qui intègrent plusieurs composants ayant la même fonction, mais dont les architectures varient. Il existe plusieurs sources d’hétérogénéité dans un système de calcul, par exemple :
— pour un système de stockage de données avec l’association d’un disque dur (Hard Disk Drive (HDD)) et d’un disque statique à semi-conducteur (SSD).
— pour un système mémoire avec l’association d’une mémoire vive volatile (Random Access Memory (RAM)) et d’une mémoire vive non volatile (Non-volatile RAM (NVRAM))
— un processeur multi-cœurs dont les cœurs utilisent des jeux d’instructions différents.
— un système de calcul par l’association de processeurs et de coprocesseurs.
Les systèmes hétérogènes étudiés dans le cadre de cette thèse s’inscrivent dans cette dernière catégorie. Cette forme d’hétérogénéité dans un système de calcul permet d’apporter une réponse au problème de la consommation énergétique [42]. Ce problème est lié, d’une part, à la perte d’efficacité des processeurs multi-cœurs et, d’autre part, à l’augmentation de leur consommation énergétique. malgré le gel de leur fréquence d’horloge, les microprocesseurs ont vu leur enveloppe thermique (TDP) légèrement croître (symbolisée par des croix vertes). Pour contenir cette chaleur, des techniques de refroidissement actives sont utilisées. Celles-ci participent à l’augmentation de la consommation énergétique globale d’un système de calcul. Dans le même temps, les besoins applicatifs ont augmenté eux aussi. Pour satisfaire ces besoins, les systèmes de calcul deviennent de plus en plus grands et donc plus énergivores. Les enjeux climatiques actuels nous poussent à concevoir des systèmes de calcul économes en énergie. Ainsi, aujourd’hui, l’efficacité énergétique est devenue une métrique aussi importante que la vitesse de traitement pour évaluer les performances d’un système de calcul. Un coprocesseur est une ressource de calcul dont l’architecture est optimisée pour réaliser certains types de traitement. Ils sont intégrés dans les systèmes de calcul pour agir comme des accélérateurs matériels. Leur usage typique consiste à déporter les portions d’une application dont l’intensité arithmétique est élevée.
Architectures de processeurs et coprocesseurs pour le calcul générique
L’architecture d’un ordinateur tel qu’on le connait est basée sur l’architecture de von Neumann (nommée en référence au mathématicien John von Neumann) . Celle-ci est organisée autour d’un processeur (Central Processing Unit (CPU)) qui contrôle l’ordinateur. Les données et instructions des programmes sont stockées dans une mémoire principale. L’utilisateur interagit avec l’ordinateur par des périphériques d’entrée (Input) et de sortie (Output). Pour exécuter un programme, le CPU charge les instructions depuis la mémoire. Ces instructions décrivent le traitement qui doit être appliqué aux données du programme. Le CPU accède à ces données et les stocke temporairement dans ses registres internes, puis réalise des opérations dessus avec son unité arithmétique et logique (Arithmetic Logic Unit (ALU)). Les périphériques sont également utilisés pour augmenter les fonctionnalités de l’ordinateur, par exemple : inclure un système de stockage permanent, interconnecter l’ordinateur à d’autre systèmes d’information ou ajouter des coprocesseurs.
Architecture d’un processeur pour les serveurs de calcul
Depuis le début des années 2000, les processeurs deviennent de plus en plus parallèles en intégrant plusieurs cœurs de calcul. Aujourd’hui, les CPU conçus pour les serveurs de calcul intègrent plusieurs dizaines de cœurs. Trois classes de composants se distinguent : les unités de calcul (en bleu), la mémoire (en rouge) et les systèmes de communication (en vert). Les unités de calcul (cœurs du processeur) sont regroupées en plusieurs grappes (clusters) reliées par un réseau sur puce (Network on Chip (NOC)). La mémoire est organisée en plusieurs niveaux de caches. Chaque cœur possède un cache privé appartenant au premier niveau (Cache L1) qui est segmenté pour contenir les données et les instructions des programmes. Chaque grappe intègre un cache du deuxième niveau (Cache L2) qui est partagé entre ses cœurs. Un troisième niveau de cache (Cache L3) peut être utilisé pour unifier tous les caches L2. Le cache L3 peut également être partitionné et physiquement réparti. Dans ce cas, chaque partition est directement interfacée avec une ou plusieurs grappes. Cependant, toutes les grappes peuvent accéder à l’ensemble des partitions. Le réseau sur puce est utilisé pour transférer les données. Plusieurs topologies de NoC existent, par exemple : une grille, un anneau ou un crossbar permettant de faire une connexion point-à-point entre toutes les grappes. La répartition physique du cache L3 conduit à des accès à la mémoire non uniformes (Non Uniform Memory Access (NUMA)). Une grappe a un accès plus rapide aux données contenues dans la partition à laquelle elle est interfacée qu’à une partition distante. Aujourd’hui, nous pouvons observer que les processeurs haut de gamme tirent profit de l’intégration sur silicium en trois dimensions pour externaliser le dernier niveau de cache sur d’autres circuits. L’intérêt est notamment d’offrir un plus grand volume d’espace mémoire cache et un plus grand débit de données. L’architecture des cœurs a également évolué dans le temps. Ainsi, un cœur de processeur autorise le traitement de plusieurs fils d’exécution en parallèle et intègre des unités de calcul vectorielles. Ces dernières réalisent une opération sur un vecteur de données en une seule instruction (Single Instruction, Multiple Data (SIMD)). Ces évolutions augmentent la puissance de calcul des processeurs.
Les processeurs intègrent également des modules leur permettant de communiquer avec le reste du système. Pour répondre aux exigences du calcul haute performance (High Performance Computing (HPC)), ces interfaces de communication ont également évolué dans le temps. Aujourd’hui, elles permettent d’échanger des données avec un plus grand débit et une plus faible latence. En 2021, le processeur qui affiche la puissance de calcul la plus élevée est le A64FX conçu par l’entreprise japonaise Fujitsu. Il s’agit d’une architecture ARMv8.2-A. Ce processeur est notamment utilisé par le superordinateur Fugaku qui est le plus puissant du TOP500 en 2021. Il intègre 48 cœurs de processeur cadencés entre 1.8 GHz et 2.2 GHz, qui sont organisés en 4 grappes. Il est doté de 32 Mio de mémoire cache L2 (4× 8 Mio). Ses cœurs de processeurs permettent d’exécuter des instructions vectorielles sur 512 bits. Une des innovations de ce CPU est d’intégrer (par une intégration en 3 dimensions) 32 Gio de mémoire à haute bande passante (High Bandwidth Memory (HBM) ) offrant 1 Tio/s de bande passante mémoire. Ces innovations lui permettent d’atteindre en théorie une vitesse de calcul de 3.4 TFLOP/s en double précision (64 bits). Son enveloppe thermique (TDP) est de seulement environ 165W, ce qui en fait un processeur efficace énergétiquement. Malgré cela, le superordinateur Fugaku est seulement 26me au classement des systèmes les plus efficaces énergétiquement du TOP500 en novembre 2021 . Ce résultat s’explique par l’absence de coprocesseur. Un processeur est généraliste. Il est capable de réaliser tous types de traitement nécessaire au fonctionnement de l’ordinateur. Tandis que, un coprocesseur est conçu et optimisé pour réaliser des opérations de calcul. Ainsi, avec le même budget énergétique un coprocesseur peut traiter un plus grand nombre d’opérations de calcul qu’un processeur.
|
Table des matières
Introduction générale
I Contexte, motivations et problématique
1 L’hétérogénéité dans les systèmes de calcul
1.1 Introduction
1.2 Architectures de processeurs et coprocesseurs pour le calcul générique
1.2.1 Architecture d’un processeur pour les serveurs de calcul
1.2.2 Architecture d’un processeur manycore
1.2.3 Architecture d’un processeur graphique
1.2.4 Architecture d’un accélérateur reconfigurable
1.3 Conclusion
1.3.1 Problématique de la thèse
2 Adéquation des architectures matérielles pour le traitement d’algorithmes de calcul scientifique
2.1 Introduction
2.2 Adéquations des architectures de coprocesseurs pour le traitement des algorithmes de calcul scientifique
2.3 Conclusion
3 Partage de données dans les systèmes de calcul à mémoires physiquement réparties
3.1 Partage des données entre les processeurs d’un système distribué multi-nœud
3.1.1 Le passage de messages avec le standard MPI
3.1.2 Les langages de programmation Partitioned Global Address Space
3.1.3 Les Mémoires Virtuellement Partagées logicielles
3.1.4 Discussion
3.2 Partage des données dans un nœud de calcul hétérogène
3.2.1 Le partage de données avec le modèle maître-esclave
3.2.2 Le partage de données avec le modèle mémoire partagée
3.3 Partage des données dans un système distribué multi-nœuds hétérogènes
3.3.1 Le modèle de programmation hybride
3.3.2 Extension d’un langage Partitioned Global Address Space (PGAS) à la programmation hétérogène
3.3.3 Un support exécutif pour les systèmes distribués et hétérogènes
3.4 Conclusion
II Intégration d’accélérateurs reconfigurables dans une mémoire virtuellement partagée logicielle : concept, modélisation et programmation
4 Intégration d’accélérateurs reconfigurables dans une mémoire virtuellement partagée logicielle
4.1 Une mémoire virtuellement partagée logicielle pour micro-serveur hétérogène
4.1.1 Topologie du système SAT
4.1.2 Protocole de cohérence
4.1.3 Allocation des données dans la mémoire partagée
4.2 Interface de l’API sur la logique programmable du FPGA
4.3 Mandataire logiciel du FPGA pour l’API
4.4 Systèmes d’interconnexions entre le processeur hôte et l’accélérateur reconfigurable
4.5 Inconvénients et propositions d’améliorations
5 Modèle de programmation pour noyaux de calcul irréguliers sur accélérateur reconfigurable dans un système distribué hétérogène
5.1 Principe général du modèle de programmation
5.2 Application du modèle de programmation à l’algèbre linéaire creuse
5.2.1 Formats de stockage compressé de matrices creuses de l’état de l’art
5.2.2 Contribution : compression de matrices creuses sous forme de chunks
5.3 Application du modèle de programmation pour le calcul par méthode des éléments finis
5.3.1 Application du principe général du modèle de programmation au traitement de maillages non structurés
5.3.2 Réordonnancement des données d’un maillage
5.4 Conclusion
6 Outil de simulation
6.1 Préambule
6.1.1 Motivations
6.1.2 Travaux connexes sur la simulation de plateforme CPUFPGA
6.2 Description du fonctionnement de l’outil de simulation
6.3 Spectre d’utilisation du simulateur et perspectives
6.4 Conclusion
III Validation du modèle de programmation
7 Plateforme de simulation et méthodologie d’expérimentations135
7.1 Caractérisation de la plateforme de simulation
7.1.1 Caractérisation des latences de communication par bus PCI entre le FPGA et le processeur
7.1.2 Caractérisation des latences des requêtes d’accès à la MVP logicielle
7.2 Méthodologie des expérimentations et calibration du modèle
7.3 Limitations de la méthodologie d’expérimentations
8 Cas d’étude 1 : Multiplication de matrices creuses
8.1 Modélisation du noyau de calcul
8.2 Jeux de matrices creuses utilisés pour les expérimentations
8.3 Résultats des expérimentations
8.3.1 Évaluation des performances du noyau de calcul en fonction de la profondeur de préchargement des données
8.3.2 Évaluation des performances du noyau de calcul en fonction du niveau de parallélisme
8.3.3 Évaluation des capacités du modèle de programmation à masquer les latences d’accès aux données distantes
8.3.4 Validation du comportement du modèle de programmation avec le jeu de grandes matrices
8.3.5 Conclusion
9 Cas d’étude 2 : Simulation de tsunami
9.1 Modélisation du noyau de calcul
9.2 Jeu de maillages utilisées pour les expérimentations
9.3 Résultats des expérimentations
9.3.1 Évaluation des performances du noyau de calcul en fonction de la taille des chunks
9.3.2 Évaluation des performances du noyau de calcul en fonction de la profondeur de préchargement des données
9.3.3 Évaluation des performances du noyau de calcul en fonction du niveau de parallélisme
9.3.4 Évaluation des capacités du modèle de programmation à masquer les latences d’accès aux données distantes
9.3.5 Évaluation de l’impact de l’ordonnancement des maillages sur les performances
Conclusion