• Aucun résultat trouvé

2.1 Les supercalculateurs : passé, présent et futur

2.1.3 Accélérateurs massivement parallèles, co-processeurs

Après une première expérience d’Intel avec les coprocesseur Intel 8087 en 1980 qui permettaient le calcul en virgule flottante pour les machines 16 bits, les serveurs de calcul actuelle utilisent ce modèle mais sur des machine 64 bits avec les accélérateurs de calculs, appelés aussi co-processeurs. Ces nouvelles architectures sont composées de plusieurs centaines de micro-processeurs, de base fréquence réalisant ainsi une très grande quantité d’opérations flottantes par seconde avec un coût électrique très bas. Dans la suite de ce paragraphe nous allons présenter les deux types les plus utilisés dans le domaine du calcul scientifique ; les cartes graphiques et les co-processeur de Intel : les Xeon Phi. Carte graphique Nvidia : CUDA (Compute Unified Device Architecture)

Depuis son lancement en 2007, un grand nombre de sociétés et de laboratoires de recherche ont choisi de développer leur application en CUDA C (Compute Unified Device Architecture).

CUDA est l’architecture des cartes graphiques NVIDIA, qui est dédiée au calcul massivement parallèle qui, contrairement au traitement traditionnel des CPU (Central Processing Unit), consiste à exécuter en même temps des tâches différentes et qui nécessite une structure de contrôle complexe et une mémoire cache pour réduire les accès à la mémoire globale.

Les GPU sont capables d’exécuter une même tâche sur des milliers de threads simultanément (SIMD : Single instruction Multiple Data) ; ce haut degré de parallélisme conduit à une augmentation potentielle des performances.

En termes de vitesse de calcul, par exemple, une carte GPU NVidia GTX 690 (5622 Gflops) est trente fois plus rapide qu’un processeur intel Core i7-3770 (200 Gflops), mais pour s’approcher des per-formances maximales atteignables par le GPU, il faut faire des efforts d’optimisation et d’organisation de données dans la mémoire du GPU. Car les performances dépendent de la vitesse du calcul, mais aussi de la vitesse des lectures et des écritures dans les différents niveaux de mémoire GPU.

Figure 2.15 – architectures GPU et CPU

La programmation sur GPU nécessite des connaissances de l’architecture et du modèle de program-mation dédié aux cartes graphiques.

Le portage d’un code développé sur CPU, validé et écrit dans un langage classique (C ou Fortran), permet d’avoir une base d’estimation de la mémoire nécessaire sur GPU et la validation des résultats,

ainsi que le calcul du gain de temps par rapport à la version CPU (Speed-up1).

CUDA C permet de définir une fonction C appelée kernel, qui est exécutée en parallèle N fois par N

threads CUDA, contrairement à une fonction qui s’exécute N fois en séquentiel sur un CPU.

Voici la forme d’une grille de calcul CUDA en 2D :

Figure 2.16 – Grille de calcul CUDA

Lorsqu’un kernel est invoqué, il s’exécute sous forme d’une grille (grid) de blocs de threads parallèles. — Une grille (grid) est un tableau à 1, 2 ou 3 dimensions (selon les caractéristiques du GPU) de

blocs.

— Un bloc (block) est un tableau à 1, 2 ou 3 dimensions de threads qui peuvent partager des ressources (shared memory).

Il faut noter que le nombre de threads par block est limité par le constructeur ; dans le cas d’une carte GTX 770, le nombre de threads est limité à 1024 x 1024 x 64 par bloc et le nombre de threads

1. Speed-up : désigne le gain de temps d’exécution d’un programme suite à l’ajout d’unités de calcul par rapport à celui d’un programme séquentiel :

S= T seq

par grille est limité à 65535 x 65535 x 65535. La mémoire

Une carte graphique NVIDIA est constituée de multiprocesseurs SM "streaming multiprocessor " eux-mêmes composés de plusieurs processeurs SP "streaming Processor ", d’une mémoire locale et de registres. Par exemple pour une carte GTX 770 :

- La mémoire globale : la plus lente (400 à 600 cycles de latence), elle est accessible en lecture et en écriture par toute la grille ;

- La mémoire partagée : rapide mais limitée par la taille (16 Ko par multiprocesseur), elle est accessible à tout un bloc ;

- Registres : rapides mais très limités (16384 par bloc), accessibles en lecture et en écriture à un thread ; - La mémoire locale : lente (200 à 300 cycles), on l’utilise quand la taille des tableaux est supérieure à la taille des registres ;

- La mémoire constante : rapide mais limitée (64 Ko), accessible en lecture seule à tous les threads ; - La mémoire texture : rapide et accessible en lecture seule à tous les threads.

La carte graphique Testa C1060 comprend trente multiprocesseurs (SM). Chaque SM comprend 8 processeurs (SP), 16 Kb de mémoire partagée, 16 384 registres de 32 bits. Chaque SM a sa propre unité qui gère la double précision, et deux unités de simple précision qui sont partagées par les huit processeurs dans le SM. Elle dispose également d’une mémoire globale de 4 Go.

Figure 2.17 – Architecture matérielle des GPU.

OpenCL (Open Computing Language) a été initialement conçu par Apple avec une collaboration de AMD, Intel et NVIDIA, puis repris par le groupe KHRONOS pour la spécification d’une première version.

OpenCL offre l’avantage de ne pas être lié à une architecture donnée, contrairement à CUDA, qui est dédié aux cartes graphiques NVIDIA. En plus, il permet l’exécution du code sur plusieurs composants (devices) CPU, GPU. Sa spécification a été inspirée par CUDA-C, avec une compilation des Kernels lors de l’exécution.

Plate-forme OpenCL

Une application OpenCL s’articule autour des notions suivantes :

les drivers des cartes installées (NVIDIA, AMD, Intel...). En général une plate-forme par constructeur. - Device : permet d’identifier les composants programmables dans chaque plate-forme, qu’il s’agisse de GPU ou de CPU, sur lesquels nous allons exécuter notre programme.

- Contexte : constitue la partie la plus importante dans une application OpenCL qui sera implémentée directement sur l’une des plates-formes.

- Command Queue : constitue une file de commandes dans laquelle on injecte des instructions de transfert des données entre le corps de l’application et les drivers, ainsi que l’exécution des Kernels. Ces derniers s’exécutent dans l’ordre de leur insertion dans la file comme une pile FIFO (First in First Out). Il existe en effet des options qui permettent une exécution asynchrone.

- Programme : permet de récupérer les codes OpenCL qui seront exécutés sur les Devices. Il sera com-pilé à l’exécution, pour ensuite créer le Kernel qui sera injecté dans la file de commandes.

la figure2.18 représente le schéma d’une application OpenCL.

Figure 2.18 – Schéma d’une application OpenCL

Modèle de programmation Pour avoir de meilleures performances, le Kernel doit être exécuté

en parallèle sur plusieurs Work-item (thread). Chaque work-item est identifié par son indice global i,0 < i < Nglobal. Les work-items sont regroupés dans les Work-groups qui s’exécutent dans un compute unit. Les work-groups sont identifiés par leur indice k,0 < k < Ngroup, les work-items sont aussi indexés localement par un indice j,0 < j < Nlocal. Donc, l’indice global est donné par la relation :

i = k∗ Nlocal + j (2.2)

et donc le nombre total des work-item est :

N global = N group∗ Nlocal (2.3)

Figure 2.19 – Grille de calcul OpenCL

La mémoireLes work-items ont accès aux différents types de mémoire. Ces mémoires ont chacune

une utilisation spécifique

– Mémoire globale : permission de lecture et d’écriture à tous les work-items.

– Mémoire constante : région de la mémoire globale pour l’utilisation de données constantes pendant l’exécution du kernel.

– Mémoire locale : mémoire dédiée à tous les work-item d’un même work-group. – Mémoire privée : mémoire dédiée à un seul et unique work-item.

Figure 2.20 – Différents types de mémoires OpenCL Processeurs many-cœurs, KNC : Knights Corner

Afin de concurrencer les processeurs graphiques, Intel a proposée une évolution naturelle des pro-cesseurs multi-cœurs, en s’appuyant toujours sur le principe de l’utilisation de propro-cesseurs avec des fréquences d’horloge relativement peu élevée mais en grand nombre. L’avantage de l’utilisation de ces processeurs par rapport à des cartes graphiques, réside dans le fait que ces cartes sont moins consom-matrices d’énergie et qu’elles sont moins complexes en terme de programmation (basées sur X86).

Figure 2.21 – Architecture d’un coprocesseur Xeon Phi KNC

Tous les efforts pour l’optimisation et la vectorisation d’un code de calcul s’exécutant sur des architectures de calcul multi-coeurs restent valables pour les architectures many-coeurs et le portage entre les deux versions est naturel et ne nécessite pas d’effort particulier. Intel ambitionnait initialement de révolutionner le marché de la carte graphique haute gamme en travaillant sur le développement des processeurs X86 massivement multi-coeurs, de nom Larrabee, après plusieurs essais et plusieurs années de recherche Intel annulait finalement ce projet, et tente une transformation pour HPC en 2010 avec une nouvelle architecture appelée MIC "Many Integrated Core". Et a lancé officiellement sa famille de coprocesseurs appelée Xeon Phi à l’occasion de la conférence internationale super-computing en 2012 avec l’annonce du premier coprocesseurs Knights Corner.

Cette première génération de Xeon Phi Intel propose une carte qui ressemble à des cartes graphiques utilisant l’interface PCIe et disposant d’un processeur gravé en 22 nm.

les accélérateurs Intel Xeon Phi sont équipés de :

— jusqu’à 61 cœurs, avec des fréquences allant de 1.2 à 1.6GHz, reliés entre eux avec un bus en anneau bi-directionnel à hautes performances.

— 4 threads par cœur(244 threads par coprocesseur). — Une mémoire globale de 8 GB.

— Deux niveaux de mémoire cache :

— une mémoire cache L1 avec 32 KB pour le cache d’instruction et 32kb pour le cache de données.

— une mémoire cache L2 avec 512KB. — SBOX : Gen2 PCI express client logic.

Figure 2.22 – Architecture d’un coprocesseur Xeon Phi KNC

Un serveur équipé des coprocesseurs Intel Xeon Phi est considéré comme le hôte de ces coprocesseurs et chaque processeur Intel Xeon peut accueillir jusqu’à 8 coprocesseurs Xeon Phi.

Le coprocesseur contient un flash et une carte SMC (System Management and Configuration) qui détiennent le bios, le bootloader (qui permet le démarrage du coprocesseur),un firmware pour le coprocesseur. Les performances théoriques peuvent atteindre jusqu’à 1 Tflops en double précision. KNL : Knights Landing

La nouvelle version des processeurs many-core d’Intel Knights Landing a été introduite durant l’année 2016, avec des processeurs gravés en 14 nm contenant plus de 8 milliards de transistors. Elle représente la plus dense carte qu’Intel n’avait jamais réalisée. Les processeurs dans une puce KNL appartiennent à la famille des atoms appelée "Silvermont". Ils constituent ainsi des vrais processeurs et non pas des coprocesseurs qui passaient par le PCie dans le cas des Knights Corner (KNC). Cette carte est constituée d’une grille 2D de processeurs, chaque processeur ayant deux unités de traitement vectorielle cette fois-ci qui permet d’utiliser les nouveaux jeu d’instruction AVX 256 à 512 bits. Les processeurs sont liés entre eux avec une interconnexion de maille en 2D, ils sont liés également à deux contrôleurs de mémoire qui sont utilisés pour alimenter le système avec une mémoire RAM, qui peut atteindre une capacité de 384 GB et qui offre une bande passante d’environ 90Go/s avec le

benchmark STREAM. Cette carte est constituée aussi de 8 cartes mémoires de la nouvelle génération

de mémoire appelée MCDRAM (Multi-Channel DRAM) conçues spécialement pour cette gamme de coprocesseurs et qui peuvent atteindre une bande passante allant jusqu’à 900 GB/s. Ainsi le KNL peut fournir une très haute bande passante, une performance en double précision qui peut atteindre 3 Tflops en double précision et 6 Tflops en simple précision ce qui lui permet d’achever 3 fois plus performances que la version précédente avec la suppression du bus PCIe de La version KNC, qui constituait un goulot d’étrangement lors de la communication avec les processeurs.

Figure 2.23 – Architecture d’un coprocesseur Xeon Phi de la famille KNL

La figure ci-dessous illustre une carte KNL représentée par une grille de coeurs et résume les performances de cette carte :

Figure 2.24 – Architecture d’un coprocesseur Xeon Phi KNL

La bande passante représente la première cause du goulot d’étranglement de la plupart des

appli-cations scientifiques. Pour traiter cette demande en terme de bande passante, la 2ème génération des

Xeon Phi KNl contient de la mémoire MCDRAM, plus proche des cœurs. Ce type de mémoire cohabite avec une mémoire RAM classique de type DDR4.

Avec ces deux types de mémoires existant dans le KNL nous avons trois modes de fonctionnement, configurables au démarrage de la machine, qui sont : Cache mode, flat mode et hybride mode.

Le Flat mode utilise la totalité de la MCDRAM comme une mémoire adressable, tandis que le mode cache utilise la MCDRAM comme étant un cache, le mode hybride lui réalise un mélange des deux modes précédents, il utilise une portion de la MCDRAM comme une mémoire cache et une deuxième portion comme une mémoire adressable. La mémoire adressable est utilisée par le programmeur avec

une allocation explicite des variables tandis que la mémoire cache n’est pas vu par le système d’ex-ploitation (OS) et sera utilisée par le processeur entre la L2 et la platforme DDR4. Les sections qui suivent représentent les trois modes de cache :

— Le mode cache :

Quand le Knights Landing est configuré en mode cache, toute la mémoire MCDRAM est utilisée comme un niveau de mémoire cache, elle sera traitée comme le dernier niveau de cache (LLC : Last Level Cache), qui sera localisé entre la mémoire DDR4 et le niveau de cache L2.

L’avantage dans l’utilisation de cette configuration réside dans la gestion de la mémoire qui est gérée par la plat-forme et qui sera transparente pour l’application, donc il n’y a pas d’action spécifique par le développeur pour l’utilisation de la mémoire MCDRAM dans l’application. Ce type de configuration est utile pour les développeurs non familiarisés avec l’optimisation ou pour des applications difficiles à optimiser. L’inconvénient de l’utilisation de la plate-forme avec le mode cache réside dans l’augmentation potentielle de la latence d’accès à la mémoire MCDRAM.

Figure 2.25 – Illustration du mode cache du KNL

— Le mode Flat :

Quand le KNL est configuré en mode Flat, la totalité de la mémoire MCDRAM est adressable, cette mémoire partage l’espace d’adressage physique avec la DDR4 et elle sont toutes les deux "cachées" par le cache L2. En prenant en compte l’architecture NUMA (Non Uniform Memory Acces), la portion de la mémoire MCDRAM est exposée comme un noeud NUMA séparé des cœurs de processeurs, et un deuxième nœud de calcul contenant tous les cœurs et la mémoire DDR4.

L’avantage de cette configuration est que le développeur a plus de flexibilité et peut gérer et contrôler les allocations mémoire dans la MCDRAM contrairement à l’utilisation en mode Cache. Les applications optimisées et qui rentre dans le MCDRAM (<= 16 GB) peuvent être très performantes dans ce mode comparé à un mode Cache.

Toutefois, l’utilisation de la MCDRAM en mémoire adressable nécessite plus d’implication dans le développement comparé à un mode cache, l’utilisation de cette mémoire est complètement gérée par le développeur, qui doit spécifier la portion alloué sur la DDR4 et celle alloué dans la MCDRAM. ce qui rend les optimisations mémoire difficiles surtout dans le cas des applications industrielles complexes.

Figure 2.26 – Illustration du mode Flat du KNL

— Le mode hybride :

Quand le KNL est utilisé en mode hybride, une portion de la MCDRAm est utilisée comme une mémoire cache et l’autre partie comme mémoire adressable. Le ratio entre les deux est choisi dans les réglages au démarrage. La mémoire adressable se comporte comme dans le mode Flat et la mémoire cache comme le mode cache, ce mode est utile dans le cas de l’utilisation des KNL dans un cluster de calcul avec plusieurs utilisateurs et plusieurs types d’applications, et quand les applications ne sont pas toutes adaptées pour utiliser la MCDRAM comme mémoire adressable.

Figure 2.27 – Illustration du mode hybride du KNL

Documents relatifs