Portage de l'unité de traitement graphique pour les applications HPC

HPC
Écrit par Daniel Vanzo, le 19 juin 2019
 
La puissance de calcul élevée est requise pour diverses applications industrielles et de recherche. Elle vise à simuler la météo, les accidents de voiture, les moteurs d'avion, les réacteurs nucléaires, les interactions fondamentales, la structure des bâtiments et d'autres encore.

Calcul par Unité de Traitement Graphique

Le calcul par Unité de Traitement Graphique offre de grandes opportunités pour les applications de haute performance. La puissance de calcul élevée est requise pour diverses applications industrielles et de recherche. Ces applications visent à simuler la météo, les accidents de voiture, les moteurs d'avion, les réacteurs nucléaires, les interactions fondamentales, la structure des bâtiments et d'autres encore.

La liste TOP500 répertorie certains des supercalculateurs les plus puissants au monde, et on ne peut que remarquer la consommation électrique énorme de ces supercalculateurs, atteignant parfois des dizaines de mégawatts. Cependant, cela soulève deux défis : obtenir suffisamment de puissance électrique pour les alimenter et être capable de dissiper toute la chaleur générée. Par conséquent, l'accent est mis sur l'obtention de plus de puissance de calcul tout en maintenant une faible consommation d'énergie.

Comme la consommation d'énergie est une fonction quadratique de la fréquence d'horloge, la tendance des dernières années a été de réduire la vitesse d'horloge et d'ajouter plus de cœurs de calcul. À l'extrême de cette idée se trouvent les GPUs (Unités de Traitement Graphique) qui sont composés de plusieurs milliers de cœurs tout en étant cadencés à environ 1,5 GHz. En comparaison, un CPU classique est composé de quelques dizaines de cœurs cadencés entre environ 2 GHz et 3 GHz. Un de ces cœurs de GPU est beaucoup moins puissant qu'un cœur de CPU, mais il y en a beaucoup. Cela permet une grande puissance de calcul avec une consommation et une dissipation de chaleur relativement faibles.

La liste Green500 est similaire à la liste TOP500, mais elle classe les supercalculateurs selon leur efficacité énergétique plutôt que leur puissance de calcul. Dans la liste de novembre 2018, dix-huit des vingt et un supercalculateurs classés dans la liste Green500 utilisent des GPUs.

Calcul par Unité de Traitement Graphique, opportunités et défis

Les Unités de Traitement Graphique ont un grand potentiel, bien qu'il y ait deux défis à relever lors de leur utilisation :

  • L'algorithme doit être capable de répartir efficacement la charge de travail sur des milliers de cœurs. Cela nécessite un haut niveau de parallélisme à exposer.
  • Le GPU agit comme un coprocesseur, ce qui signifie que le CPU décharge le travail sur le GPU et récupère le résultat à la fin du calcul. Cela implique un transfert de données entre le CPU et le GPU, ce qui peut ralentir le calcul global.

Aneo travaille avec un intégrateur de systèmes HPC pour porter certaines applications sur l'architecture GPU et démontrer les avantages de l'utilisation de supercalculateurs basés sur des GPUs. L'accent est mis sur deux applications :

  • Simulation de la QCD sur réseau : simule l'interaction forte fondamentale à l'intérieur des neutrons ou des protons.
  • Simulation de la dynamique des fluides : simule la dynamique des fluides avec des réactions chimiques, comme dans un moteur d'hélicoptère.

Simulation de la QCD sur réseau

L'application de QCD sur réseau nécessite que certaines parties de son calcul soient effectuées avec une grande précision, supérieure à ce que permettraient les nombres flottants sur 64 bits. L'implémentation initiale utilise une bibliothèque CPU qui constitue un goulot d'étranglement pour deux raisons : d'une part, parce que l'implémentation de la bibliothèque CPU est plutôt lente, et d'autre part, parce que les données sont copiées du GPU vers le CPU pour cette partie de haute précision, puis copiées de nouveau vers le GPU pour le reste du calcul. Cette partie du calcul est en fait un algorithme appliqué des millions de fois à des données différentes. Les GPUs sont des candidats idéaux pour ce type de charge de travail car il y a de nombreuses tâches indépendantes identiques à effectuer et le grand nombre de cœurs de calcul GPU peut tous travailler simultanément.

Le calcul de haute précision n'est pas pris en charge nativement par les GPUs, ni par la plupart des CPUs. Une manière de faire du calcul de haute précision est de représenter un nombre avec deux variables à virgule flottante : la première variable codant pour la partie haute du nombre, la seconde variable codant pour la partie basse du nombre. Une variable à virgule flottante sur 64 bits permet une précision allant jusqu'à 16 décimales significatives. L'utilisation de deux variables à virgule flottante sur 64 bits pour représenter un nombre permet alors une précision allant jusqu'à 32 décimales significatives.

Un algorithme de type deux nombres à virgule flottante a été implémenté avec une bibliothèque de haute précision GPU. Cela donne à ce cas d'utilisation une grande accélération par rapport à l'implémentation de référence CPU. Cela a également nécessité moins de communications CPU/GPU. À la fin de la journée, cela rend cette partie du calcul négligeable par rapport au temps de calcul global.

Simulation de la dynamique des fluides

L'optimisation par Unité de Traitement Graphique nécessite parfois de réécrire des parties entières de l'application et de les rendre quelque peu obscures pour les personnes non initiées. Ce projet nécessite de porter le code sur l'architecture GPU en utilisant une méthode non intrusive, en conservant la structure du code telle quelle et en rendant les modifications compréhensibles pour les non-experts en GPU. Les solutions basées sur des directives sont les outils de choix pour cette situation.

L'application implique des structures de données complexes, imbriquées et enchaînées, ce qui rend difficile la copie et l'utilisation des données sur le GPU sans modifier les structures de données. Les transferts de données sont gérés méticuleusement à l'intérieur des routines qui créent, mettent à jour et suppriment ces structures. Cela minimise la communication CPU/GPU et permet de ne copier que les données nécessaires au calcul.

À chaque itération de l'algorithme, tous les nœuds impliqués dans le calcul échangent des données. Souvent, même avec des codes accélérés par GPU, les échanges de données sont gérés par le CPU. Pour illustrer cela, soit deux nœuds nommés A et B, chacun composé d'un CPU et d'un GPU. Lorsqu'un échange de données de nœud A à nœud B est nécessaire, les données doivent d'abord être copiées du GPU A vers le CPU A, puis du CPU A vers le CPU B et enfin du CPU B vers le GPU B. Les transferts CPU/GPU ajoutés sont très coûteux en temps, donc l'implémentation devrait les éviter. Cela est possible en copiant directement les données du GPU A au GPU B car ils sont connectés au réseau.

En conclusion, faire en sorte que tout le calcul se fasse sur le GPU et éviter la plupart des transferts CPU/GPU devrait donner une application plus efficace.

En savoir plus sur l'opportunité des unités de traitement graphique ici.