L’art du calcul haute performance
(theartofhpc.com)- The Art of HPC est une série de manuels sur le calcul haute performance créée par Victor Eijkhout, du TACC, qui réunit en un seul parcours les bases du calcul scientifique, la programmation parallèle et les outils de développement
- Le premier volume est un ouvrage de contexte sur le calcul scientifique qui explique comment l’architecture des ordinateurs, l’arithmétique, l’algèbre linéaire et les EDO/EDP s’articulent dans les calculs à grande échelle
- Le deuxième volume explique la programmation parallèle, principalement autour de MPI et OpenMP, et inclut aussi de courtes sections sur PETSc, Kokkos, Sycl et Co-array Fortran
- Le troisième volume traite de C++17 et Fortran2008 utilisés en programmation scientifique et d’ingénierie, et peut être lu aussi bien par des débutants que par des programmeurs C
- Le quatrième volume présente les outils de workflow de développement nécessaires au travail HPC réel, comme les compilateurs, les systèmes de build et la gestion du code source
Structure des manuels The Art of HPC
- The Art of HPC est une série de manuels sur le calcul haute performance créée par Victor Eijkhout, du TACC
- La série traite séparément, volume par volume, du contexte du calcul scientifique, de la programmation parallèle, des langages de programmation scientifique et de l’écosystème de développement HPC
Périmètre par volume
-
Volume 1: The Science of Computing
- Traite des connaissances générales nécessaires pour comprendre le calcul scientifique
- Inclut l’architecture des ordinateurs, l’architecture des ordinateurs parallèles, l’arithmétique informatique, l’algèbre linéaire et les EDO/EDP
- Explique comment ces éléments se combinent dans les calculs à grande échelle et constitue, avec le Volume 2, l’ensemble couvrant le « quoi/pourquoi » et le « comment » du HPC
-
Volume 2: Parallel Programming for Science and Engineering
- Volume consacré à la programmation parallèle, importante dans le calcul scientifique
- Présente principalement les versions modernes de MPI et OpenMP
- Inclut aussi de courtes sections sur PETSc, Kokkos, Sycl et Co-array Fortran
- MPI et OpenMP sont abordés en C, Fortran et C++, tandis que MPI inclut aussi Python
-
Volume 3: Introduction to Scientific Programming
- Enseigne le C++17 moderne et Fortran2008, sur fond de C/C++ et de Fortran, très utilisés en programmation scientifique et d’ingénierie
- Adopte une approche qui privilégie C++17 plutôt que C
- Peut se lire comme une introduction à la programmation scientifique en partant de zéro, ou comme un manuel d’apprentissage de C++ pour les programmeurs C
- Inclut plusieurs longs projets de programmation
-
Volume 4: HPC Carpentry
- Met l’accent sur le fait que l’écosystème du calcul scientifique ne se limite pas aux langages de programmation et aux systèmes de programmation parallèle
- Présente les éléments nécessaires à un workflow scientifique, comme les compilateurs, les systèmes de build et la gestion du code source
- Relève davantage d’une collection d’introductions adaptées au workflow scientifique que d’un ouvrage de référence exhaustif
1 commentaires
Commentaires de Hacker News
L’aspect matériel/datacenter de ce sujet est tout aussi intéressant
J’ai travaillé autrefois chez AWS côté logiciel/services, et il m’arrivait d’aller écouter discrètement les présentations de l’équipe datacenter
La plus grande prise de conscience, c’est que développer la puissance de calcul dans un datacenter relève en réalité davantage d’un problème de thermodynamique que d’informatique à proprement parler. La densité des nœuds devient si élevée qu’il est extrêmement difficile d’y faire entrer l’électricité, d’en extraire la chaleur, et d’ajouter à cela toutes sortes de redondances. Même quand on trouve une inefficacité, on ne peut pas la corriger comme avec une mise à jour logicielle
C’était il y a environ 10 ans, donc certaines choses ont sans doute changé depuis, mais il est étonnant qu’Amazon, qui a commencé comme librairie en ligne, se retrouve en première ligne de la résolution de problèmes de thermodynamique
Avec le Cray-2, il a adopté une approche encore plus extrême, avec une architecture de refroidissement qui plongeait des empilements denses de cartes de circuits imprimés dans un liquide spécial non conducteur appelé Fluorinert™ : « The Cray-2's unusual cooling scheme immersed dense stacks of circuit boards in a special non-conductive liquid called Fluorinert™ »
L’eau a une très grande capacité thermique et permet de refroidir rapidement de gros volumes jusqu’à la température optimale. Il faudrait toujours des ventilateurs et de la climatisation pour évacuer la chaleur des composants qui ne peuvent pas être refroidis par liquide, mais pour les composants très énergivores comme les CPU, GPU ou moteurs de calcul, on peut extraire directement et très vite une quantité énorme de chaleur
La complexité et le risque des fuites posent certes problème, mais à l’échelle des datacenters d’Amazon, cela ne me semble pas être une inquiétude si majeure
Je suis curieux de savoir à quoi ressemblent les technologies de refroidissement de pointe
Il est intéressant de voir que le HPC semble parfois assez abstrait du matériel
Les livres semblent beaucoup traiter de programmation SPMD, d’algorithmes et de structures de données, de parallélisme des tâches, de synchronisation, etc., mais assez peu de détails d’architecture informatique comme les sous-systèmes mémoire des supercalculateurs, les interconnexions à haute bande passante comme CXL, ou l’architecture des GPU
Je me demande si les abstractions et les outils sont déjà suffisamment bons pour qu’on n’ait pas à se soucier de ces détails, ou si les praticiens du HPC manipulent beaucoup de boutons de boîte noire pour en tirer des performances
En règle générale, pour une scalabilité optimale, la topologie du logiciel doit correspondre autant que possible à celle du matériel. Un logiciel HPC efficace est fortement influencé par les caractéristiques du matériel
Quand je demandais la documentation système, matérielle et d’architecture, plutôt que la documentation de programmation, pour écrire du code destiné à un nouveau matériel HPC, les gens étaient toujours surpris. Comprendre la conception du matériel rendait évident, à partir des premiers principes, la manière dont il fallait concevoir le logiciel par-dessus. La documentation de programmation contenait pas mal de demi-vérités destinées à donner aux développeurs l’impression que les choses étaient plus simples qu’elles ne l’étaient vraiment
Certaines plateformes HPC, pour paraître « faciles à utiliser », ont constamment mal expliqué ce que les développeurs devaient faire pour obtenir des performances maximales ; et lorsque le logiciel était écrit de la façon suggérée par le marketing, il n’arrivait pas à atteindre les performances dont le silicium était capable, ce qui conduisait parfois à de gros échecs
On peut écrire du code HPC au-dessus d’abstractions, et beaucoup le font effectivement, mais les pertes de performance et de scalabilité sont souvent inévitables et se comptent en multiples entiers. Comme pour les autres logiciels, ces pertes étaient souvent acceptées si cela permettait à des développeurs moins expérimentés de concevoir le code
Le HPC, comme les autres logiciels, compte beaucoup de personnes qui, même si elles sont officiellement des développeurs professionnels, peinent à produire régulièrement de bons résultats. Une grande partie du matériel coûteux utilisé en HPC existe pour atténuer les pertes de performance dues à une mauvaise conception logicielle
Si l’on veut des performances maximales, il n’y a pas de raccourci autre que comprendre réellement comment le matériel fonctionne. Ce n’est pas différent du logiciel classique ; en HPC, les systèmes matériels sont simplement plus grands et plus complexes
Mais ce n’était pas ce à quoi je m’attendais. Je pensais faire davantage de travail orienté performance, analyser des chiffres et extraire jusqu’à la dernière goutte de performance du cluster. Pour être honnête, au début il n’y avait même pas de monitoring. Je l’ai mis en place moi-même, mais il est à peine utilisé. De temps en temps, la direction demande « à quel point le cluster est occupé », par exemple pour justifier le budget
La plupart de « l’optimisation » consiste à vérifier que les gens ne demandent pas 384 CPU alors que leur script n’en utilise que 16, ou à tester jusqu’à combien de CPU un logiciel donné peut fonctionner sans dégradation des performances. Je n’ai ouvert le profiler Intel que deux fois
L’essentiel du travail ressemble plutôt à de l’assistance aux chercheurs. En général, il s’agit d’exécuter des programmes commerciaux ou open source et de résoudre des problèmes, ou de prendre du code écrit par une autre équipe sur un autre cluster et de le faire compiler et tourner sur le nôtre. Je fouille dans du mauvais code Python et j’essaie de compiler des projets C++ issus de clusters plus modernes dans un environnement CentOS 7
C’est amusant à sa manière. Comme j’ai travaillé avec plusieurs langages, j’aime faire fonctionner les choses et creuser les crashs et les traces de pile. Quand on manipule de grosses machines, on finit par avoir des repères faussés en voyant un serveur avec « seulement » 128 Go de RAM ou 20 To de disque
Ce qui fait peur, c’est que ces résultats sont utilisés dans le monde réel, alors que les personnes qui lancent les simulations ne font pas toujours les choses correctement. J’ai déjà vu du code incorrect, du code source mélangé, des données utilisées qui n’étaient pas celles qu’ils pensaient utiliser, ou encore un énorme bug présent depuis trois ans. Dans ces cas-là, on se demande si tout le travail effectué sur le sujet n’est pas invalidé
L’inconvénient, c’est qu’un grand nombre de postes HPC exigent un master, alors qu’il s’agit essentiellement d’exploiter des clusters. Je ne comprends pas bien. Je n’écris pas le logiciel que j’exécute, et je ne gère pas non plus un cluster TOP500 de dernière génération. Je ne fais que mettre plusieurs machines en réseau et y faire tourner du code
D’après mon expérience avec des développeurs CUDA, on manipule beaucoup de boutons pour obtenir des performances. Le Shmoo Plot (https://en.wikipedia.org/wiki/Shmoo_plot, aussi appelé « wedge » dans certains secteurs) est l’un des outils essentiels de l’optimisation au quotidien
Cela dit, je ne sais pas si je qualifierais cela de boîte noire. Au final, cela peut se ressembler. Même quand on sait ce que font les boutons et comment ils fonctionnent, et même avec des hypothèses fondées, les mesures réservent souvent de grosses surprises. La première règle de l’optimisation, c’est de mesurer
Je repense toujours au premier chapitre du « Black Book » de Michael Abrash, « The Best Optimizer is Between Your Ears » http://twimgs.com/ddj/abrashblackbook/gpbb1.pdf. Ce n’est pas du HPC moderne, c’est plutôt centré sur les jeux PC, mais c’est un excellent texte qui illustre bien la philosophie de la haute performance
À propos des abstractions, le réglage le plus lourd des boutons devrait idéalement se faire à la fin du processus d’optimisation. En effet, si l’on refactorise ou modifie quelque chose, il faut refaire ce réglage. De petits changements dans le spill de registres ou les schémas d’accès au cache peuvent remettre complètement à zéro des réglages fins comme la configuration des threads, le cache ou la taille de la mémoire partagée
Il faut malgré tout faire une quantité raisonnable de réglage des boutons en cours de route, pour vérifier, équilibrer et se construire une intuition de l’espace de performance autour du code
Sur le matériel x86_64 actuel, il n’existe pas vraiment de sous-système mémoire de supercalculateur. Ce ne sont que des systèmes NUMA sophistiqués, et le plus gros problème consiste à garder la mémoire près des cœurs, c’est-à-dire à maintenir les données localement dans le nœud NUMA concerné afin de réduire la latence
Le mapping des ressources est géré par le scheduler. Celui-ci connaît le matériel, crée un cgroup qui satisfait les exigences tout en étant optimisé autant que possible, puis lance l’application dans ce cgroup
Le roi actuel des interconnexions hautes performances est InfiniBand, qui accélère MPI au niveau du fabric. Il permet de transmettre des messages, de faire des diffusions et de réduire des résultats très rapidement. Lorsqu’un message arrive, il est déjà réduit ; et pour une diffusion, il suffit d’envoyer un seul message, qui est diffusé par la couche fabric. Les cartes IB à contextes multiples disposent de nombreuses files, ce qui permet d’exécuter plusieurs tâches MPI sur un même nœud/une même carte avec isolation des files/contextes
Quand on utilise un framework pour les tâches GPU, la structure et les optimisations sont généralement gérées automatiquement à ce niveau. Le gros du travail est en général fait par les développeurs du framework. Les pilotes NVIDIA relèvent eux aussi de la magie noire pure et prennent en charge une partie de l’optimisation. Les connexions entre GPU sont assurées par le fabric physique, et gérées par le pilote et son propre démon
Si le goulot d’étranglement est côté CPU, les bibliothèques sont généralement réglées à la main par le fournisseur. C’est le cas d’Intel MKL, BLAS, Eigen, etc. D’après mon expérience, Eigen contenait des indications et des optimisations propres à chaque processeur
Ce à quoi il faut faire attention, c’est compiler le code pour la bonne architecture et vérifier que le matériel sur lequel il s’exécute peut satisfaire les exigences. Par exemple, éviter trop d’accès mémoire aléatoires, bien s’aligner sur le préfetcher et le prédicteur de branchement si l’on veut aller « aussi vite que possible » sur un nœud, et ne pas abuser des accès disque
Côté calcul numérique, l’essentiel est de garder les tâches indépendantes pour permettre le parallélisme au niveau des instructions/la vectorisation, d’éviter les calculs inutiles et de ne pas abuser de MPI, autrement dit de réduire les échanges entre nœuds au strict nécessaire
C’est plus facile à dire qu’à faire, mais avec l’habitude, penser à ce genre de choses devient une seconde nature. À condition que ce type de travail corresponde à vos goûts
À la fois oui et non
MPI et OpenMP sont les principaux moyens d’abstraire le matériel en HPC. MPI est une abstraction du calcul parallèle à mémoire distribuée, tandis qu’OpenMP est une abstraction du calcul parallèle à mémoire partagée. Beaucoup de chercheurs écrivent leur code uniquement avec ces deux outils, et les utilisent souvent tous les deux dans le même code. Quand on les emploie, on n’a généralement pas à se soucier de la plupart des détails d’architecture
Cela dit, les chercheurs qui aiment pousser l’optimisation touchent à beaucoup de petits détails architecturaux pour gagner encore en performances. Par exemple, le déroulage de boucle est assez courant et, personnellement, je trouve que cela peut devenir assez déroutant. Je me souviens vaguement avoir entendu dire qu’en raison d’une certaine architecture CPU, on préférait les additions aux multiplications pour vectoriser les opérations, mais je ne l’ai jamais vu en pratique
Éviter les ratés de cache est aussi un grand sujet. Certains codes sont écrits de façon à garder les informations les plus nécessaires dans le cache CPU plutôt qu’en mémoire. La plupart des codes se contentent de garantir un parcours par colonnes pour les opérations sur tableaux en Fortran, et par lignes en C, mais le concept peut être poussé plus loin. Si l’on connaît la taille du cache du processeur, on peut aussi optimiser certaines opérations pour garder toutes les informations nécessaires dans le cache et minimiser les ratés de cache. Je ne l’ai jamais vu en pratique, mais c’était un sujet beaucoup traité dans un cours de calcul scientifique que j’ai suivi en 2013
L’utilisation ou non d’un GPU particulier dépend fortement du problème à résoudre. Certains problèmes se prêtent très bien aux GPU, d’autres sont trop difficiles. Malheureusement, je ne connais pas bien cette partie
Je suis impressionné que Victor ait rassemblé des ressources aussi excellentes
Je ne le connais pas personnellement, mais dans les années 1990, pendant mon doctorat à l’UT Austin, j’ai terminé mes recherches en utilisant des ressources gérées par le TACC (Cray Y-MP, IBM SP/2 Winterhawk, ainsi que le nom d’hôte Lonestar, qui désignait alors un Cray T3E). L’un des membres de mon jury de thèse y est encore. Si ma mémoire est bonne, le TACC s’appelait alors HPCC ou CHPC
À l’époque, les programmeurs devaient paralléliser eux-mêmes leur code et, dans mon cas, j’utilisais MPI sur un Cray T3E sous UNICOS. Le domaine en était encore à ses débuts, il fallait donc aussi comprendre un minimum le matériel. Je résolvais les problèmes en lisant les classeurs à anneaux gris de Cray et le livre de Gropp et al. que j’avais sous la main, et bien sûr le contact très compétent mentionné plus haut m’a beaucoup aidé
Le temps ne s’arrête jamais
C’était un peu éloigné de mon domaine, mais très intéressant. Je compte aussi regarder le reste, et je recommande à toute personne intéressée d’y jeter un œil
Je m’intéresse à la gestion matérielle dans le HPC
Je me demande comment les problèmes sont détectés et diagnostiqués, comment ils sont associés à des actions comme le redémarrage, la réinstallation ou la réparation, et comment ces opérations sont planifiées et optimisées pour fournir le meilleur niveau de service
Je m’intéresse aussi à la façon de faire quand plusieurs objectifs doivent être optimisés simultanément, comme la disponibilité des nœuds et le débit global, à l’effet des différentes topologies sur tout cela, à l’impact d’autres contraintes, et plus généralement à la manière d’aborder ces problèmes du point de vue de la dynamique des systèmes
Je n’ai pas trouvé beaucoup de ressources qui traitent bien ce sujet. Si vous en connaissez, je serais preneur
La théorie des files d’attente paraît triviale et facile quand on la découvre, mais elle comporte beaucoup de problèmes ouverts
Par exemple, les indicateurs de performance d’un système avec arrivées aléatoires, temps de service indépendants et k serveurs (M/G/k) restent un problème ouvert
https://www.sciencedirect.com/science/article/pii/S0895717704905341
Contrairement à ce qu’on pourrait croire, la théorie des files d’attente compte vraiment beaucoup de problèmes ouverts
Meta avait quelques bonnes vidéos YouTube expliquant les problèmes liés à la gestion de GPU à cette échelle
Meta publie également beaucoup d’articles, de billets de blog et de projets open source sur son site d’ingénierie [2]
James Hamilton, chez AWS, fait lui aussi presque chaque année une présentation sur l’infrastructure. Cela vaut la peine de regarder celles de plusieurs années [3]
[1] https://youtu.be/69PrhWQorEM?si=u7vh_Um6SQNoyeFH
[2] https://engineering.fb.com/category/data-center-engineering/
[3] https://youtu.be/AyOAjFNPAbA?si=nFRJVcQI4EiamC-O
En gros, il optimise au niveau de la charge de travail, ici des tâches de deep learning, afin de permettre le redimensionnement des tâches et la préemption
[1] https://arxiv.org/pdf/2202.07848.pdf
En 2013, j’ai suivi un cours de calcul scientifique
C’était un cours proposé à la fois en informatique et en mathématiques appliquées. Le problème, c’est que le domaine était globalement trop vaste, si bien que de nombreux sujets, dont le HPC et la programmation parallèle, n’étaient abordés que très superficiellement. Je ne regrette pas de l’avoir suivi, mais c’était trop large pour les applications qui m’intéressaient
Je n’ai pas regardé depuis quelques années quels cours sont proposés, mais quand j’étais étudiant en master/doctorat, un cours dédié couvrant le calcul parallèle pendant tout un semestre m’aurait vraiment été utile. Il aurait surtout fallu un cours qui approfondisse certains algorithmes et structures de données propres au calcul parallèle et distribué
Dans le cours de calcul scientifique que j’ai suivi, ces sujets étaient traités beaucoup trop rapidement, comme si l’on pouvait savoir dès la première tentative exactement comment paralléliser correctement. Par la suite, comme beaucoup de gens dans le HPC, j’ai beaucoup appris seul et auprès de collègues au fil des années, mais si ces livres avaient fait partie d’un cours dédié sur un semestre, ils auraient été extrêmement précieux
Il est étonnant que l’auteur ait produit des livres aussi complets, incluant même une formation à C++ et aux outils Unix, et les ait partagés gratuitement
Même sans être spécifiquement consacrés au HPC, tous les programmeurs ont quelque chose à en apprendre
Parmi les ressources liées, il y a aussi le livre “Matters Computational” de Jorg Arndt et la bibliothèque FXT : https://www.jjj.de/fxt/
Je suis curieux de savoir ce que vous pensez de la méthode d’enseignement du C++ utilisée ici. Y a-t-il des inconvénients particuliers ?
J’utilise Python depuis très longtemps, je touche aussi un peu à C, C++ et CUDA, et je fais de la recherche au niveau applicatif (ML/DL) dans des environnements HPC. J’aimerais améliorer mon niveau en C++ et, en parcourant les 3 volumes, ils semblent parfaitement adaptés à mon niveau. La progression n’est pas trop lente, et plutôt que de viser l’exhaustivité, l’approche consiste à enseigner les bonnes pratiques telles que les présente l’auteur.
J’ai cherché les boucles
forbasées sur les plages,std::arrayetstd::span, et j’ai été content de voir qu’ils y étaient tous.Comme ce livre est lié au HPC, j’aimerais ajouter quelques points. Ce serait bien d’avoir des explications sur l’optimisation de la valeur de retour, la sémantique de déplacement, et, dans la section sur les fonctions récursives, l’optimisation des appels terminaux.
Je peux le recommander vivement comme ressource pour débutants.
À noter que MPI n’est qu’une des façons de faire du HPC en Python.
Si ma mémoire est bonne, ipyparallel peut exécuter des tâches MPI sur un tunnel maison.
Des chapitres sur dask-scheduler, CuDF, CuGraph (NetworkX), DaskML, CuPy et dask-labextension rendraient l’ensemble plus à jour.
Dask ne prend pas en charge le stockage des données à votre place : c’est donc à l’utilisateur de s’assurer que le stockage des données avant chaque barrière ne devienne pas un goulot d’étranglement.
Documentation Dask, High Performance Computers : https://docs.dask.org/en/stable/deploying-hpc.html
La source d’aléa peut aussi être un goulot d’étranglement. Impossible de le savoir sans profiler les tâches sur l’ensemble du cluster.
À propos des outils de traçage basés sur eBPF : https://news.ycombinator.com/item?id=31688180
Ensuite, ce serait bien d’avoir aussi des sujets comme GitOps et ChatOps, les revues de code et les révisions, ou encore les quotas de ressources de projet.
Il y a 10 ans, on m’a proposé de partager le rôle d’assistant d’enseignement pour un cours de HPC en master/doctorat, mais j’ai refusé.
À en juger par mon rapide survol, je peux dire honnêtement que si ce livre avait existé à l’époque, j’aurais saisi cette occasion.
Le cadrage en tant qu’art, qui évoque Knuth, la comparaison avec la menuiserie, et la nécessité de devenir meilleur en DevOps que son propre responsable DevOps, forment un ensemble convaincant.
Bravo à l’auteur pour son travail. UT Austin semble avoir accompli en informatique quelque chose de comparable à ce que North Texas State a fait en musique.
UT Austin est vraiment une excellente institution en matière de HPC et de méthodes computationnelles.
Quand j’ai rejoint une petite entreprise qui aidait les ingénieurs HPC d’un grand constructeur automobile, j’ai été surpris par la quantité de scripts développés en interne autour de LSF, le planificateur.
Beaucoup plus tard, en bricolant avec SLURM sur un mini-cluster personnel, j’ai découvert que les versions des logiciels de planification étaient globalement incompatibles entre elles. Autrement dit, il était impossible d’utiliser une version à l’intérieur du cluster et une autre sur les machines clientes externes.
Il fallait donc du logiciel de glue pour soumettre des tâches au planificateur depuis l’extérieur, puis récupérer les résultats plus tard. À titre personnel, je trouve que cela réduit la valeur du planificateur.
Je pensais qu’après environ 30 ans de calcul distribué haute performance, les exigences seraient bien connues et qu’au moins les protocoles d’échange de commandes et de données seraient stabilisés. Apparemment non.
sbatch/squeuesont assez stables.Il y a déjà eu par le passé des tentatives de standardisation d’une API de base pour la gestion des tâches, DRMAA étant un exemple notable. Mais DRMAA v2 n’a été implémenté que par Grid Engine et, comme il s’agissait en pratique d’une légère abstraction de son API interne, il n’a jamais bénéficié d’un support de premier ordre dans Slurm/PBS/LSF.
Dans Slurm, l’API REST est considérée comme la voie à suivre. Le problème de l’authentification est délégué, via un proxy Apache/NGINX, à n’importe quelle méthode que l’administrateur souhaite connecter. Les API de soumission de tâches de base et de statut sont désormais suffisamment stabilisées pour pouvoir être consommées à l’avenir par à peu près n’importe quelle version d’une application cliente.