8 · Outils de mesure¶
Le catalogue, avec la question qui compte vraiment : quel outil pour quelle question ? Un ingénieur HPC qui connaît trois outils et sait lequel sortir va plus vite que celui qui en connaît vingt et les essaie au hasard.
Difficulté : ★★ · ⏱ 25 h
L'arbre de décision¶
Ma question est…
│
├─ « Combien de temps ça prend ? »
│ → chronométrage manuel, `time`, `hyperfine`
│
├─ « Où passe le temps dans mon code ? »
│ → perf record + flame graph, VTune, HPCToolkit, gprof
│
├─ « Pourquoi cette boucle est-elle lente ? »
│ → compteurs matériels : LIKWID, perf stat, VTune, MAQAO
│
├─ « Est-ce limité par le calcul ou par la mémoire ? »
│ → roofline : Intel Advisor, ou calcul manuel + LIKWID
│
├─ « Pourquoi ça ne passe pas à l'échelle en MPI ? »
│ → mpiP (léger), Score-P/Vampir ou Extrae/Paraver (trace)
│
├─ « Pourquoi mes threads n'accélèrent pas ? »
│ → LIKWID, perf c2c (faux partage), numastat (NUMA)
│
├─ « Que fait mon GPU ? »
│ → Nsight Systems (chronologie), Nsight Compute (par kernel)
│
├─ « Comment mon code écrit-il ses fichiers ? »
│ → Darshan
│
├─ « Y a-t-il un bug de concurrence ? »
│ → ThreadSanitizer, Helgrind, Archer, MUST (pour MPI)
│
└─ « Combien ça consomme ? »
→ perf stat energy-pkg, nvidia-smi, IPMI, Scaphandre
Niveau 1 · Le chronométrage¶
Toujours commencer là. Un chronométrage bien fait répond à 30 % des questions.
En C ou C++ : clock_gettime(CLOCK_MONOTONIC, …) ou
std::chrono::steady_clock. Jamais time() (résolution d'une seconde), jamais
clock() (mesure le temps processeur cumulé de tous les threads, donc faux en
parallèle).
En MPI : MPI_Wtime(), avec un MPI_Barrier avant et après la phase mesurée
si l'on veut le temps de la phase et non celui du rang 0.
Sur GPU : les events CUDA, avec synchronisation explicite. Voir PGPU35.
En ligne de commande : hyperfine est nettement supérieur à time — il
répète automatiquement, calcule la médiane et l'écart-type, gère le préchauffage,
et compare plusieurs commandes.
Les cinq règles du chronométrage
- Horloge monotone, jamais l'horloge murale ajustable.
- Trois répétitions minimum, dix si la variance dépasse 5 %.
- Écarter les itérations de préchauffage (caches froids, allocation paresseuse, compilation JIT).
- Consommer le résultat, sinon le compilateur supprime le calcul.
- Mesurer les phases séparément : initialisation, calcul, E-S. Un temps total masque tout.
Niveau 2 · Le profilage par échantillonnage¶
Répond à « où passe le temps ». Le profileur interrompt le programme périodiquement et relève la pile d'appels.
perf, sous Linux, est l'outil universel et gratuit :
# Où passe le temps, avec graphe d'appel
perf record -g --call-graph dwarf ./mon_binaire
perf report
# Les compteurs de base
perf stat ./mon_binaire
# Un flame graph (avec les scripts de Brendan Gregg)
perf script | stackcollapse-perf.pl | flamegraph.pl > profil.svg
Le flame graph est la représentation la plus lisible d'un profil : chaque barre horizontale est une fonction, sa largeur est proportionnelle au temps, et l'empilement vertical est la pile d'appels.
Les autres : HPCToolkit (excellent en parallèle, échantillonnage à faible surcoût), Intel VTune (interface riche, analyse mémoire et threads), gprof (historique, par instrumentation, biaisé par le surcoût — à éviter).
Le piège de l'inlining
À -O3, le compilateur fusionne les fonctions. Le profil attribue alors le
temps à la fonction englobante, et les fonctions que vous cherchez ont
disparu. Compilez avec -O2 -g -fno-omit-frame-pointer ou
RelWithDebInfo pour profiler : on garde l'optimisation et on conserve la
pile d'appels.
Niveau 3 · Les compteurs matériels¶
Répond à « pourquoi c'est lent ». Le processeur compte les événements : cycles, instructions, défauts de cache par niveau, défauts de TLB, instructions vectorielles, cycles de blocage.
LIKWID est l'outil de référence en HPC, développé par l'équipe de Hager et Wellein :
# La topologie de la machine
likwid-topology -g
# Épingler des threads proprement
likwid-pin -c 0-7 ./mon_binaire
# Mesurer un groupe de compteurs
likwid-perfctr -C 0-7 -g MEM_DP ./mon_binaire
likwid-perfctr -C 0-7 -g FLOPS_DP ./mon_binaire
likwid-perfctr -C 0-7 -g L3CACHE ./mon_binaire
# Micro-bancs d'essai de bande passante par niveau
likwid-bench -t load -w S0:1GB
Les groupes de LIKWID sont sa grande force : plutôt que de choisir des
compteurs brutes, on demande MEM_DP et on obtient directement la bande passante
mémoire et les FLOPS en double précision, avec les formules de dérivation déjà
appliquées.
Les métriques dérivées à connaître :
| Métrique | Formule | Interprétation |
|---|---|---|
| IPC | instructions / cycles | Moins de 1 : blocages fréquents. Plus de 2 : bon |
| Taux de défauts L1 | défauts L1 / accès L1 | Au-delà de quelques pour cent : problème de localité |
| Bande passante effective | octets transférés / temps | À comparer à STREAM |
| Fraction vectorisée | instructions vectorielles / total | Proche de 0 : non vectorisé |
| Cycles de blocage mémoire | — | La part du temps passée à attendre la mémoire |
Niveau 4 · Le roofline automatique¶
Intel Advisor produit un diagramme roofline avec vos boucles positionnées dessus, en une commande. C'est l'outil le plus pédagogique du domaine : on voit immédiatement quelles boucles sont loin de la borne et lesquelles sont déjà au plafond. Gratuit dans oneAPI.
MAQAO (maqao.org, développé à l'Université de Versailles Saint-Quentin)
fait de l'analyse statique et dynamique de boucles sur binaire, et produit un
rapport qui explique les limitations : boucle non vectorisée et pourquoi,
goulot sur une unité d'exécution, accès non contigus. Outil français, orienté HPC,
peu connu et remarquablement utile.
Nsight Compute produit également un roofline pour les noyaux GPU.
Niveau 5 · Le traçage parallèle¶
Répond à « pourquoi ça ne passe pas à l'échelle ». Un profil agrège ; une trace conserve la chronologie, ce qui permet de voir les attentes, les déséquilibres et le chemin critique.
La chaîne européenne : Score-P instrumente (MPI, OpenMP, CUDA), produit des profils Cube ou des traces OTF2 ; Scalasca analyse automatiquement les traces et signale les motifs d'attente ; Vampir ou Cube visualisent.
La chaîne du Barcelona Supercomputing Center : Extrae instrumente, Paraver visualise, Dimemas simule des configurations alternatives. La visualisation de Paraver est la meilleure du domaine, et le BSC publie une méthodologie d'analyse structurée qui vaut d'être lue.
Le plus léger : mpiP, qui donne un profil MPI par fonction et par rang sans trace complète, avec un surcoût négligeable. À utiliser en premier.
Les traces deviennent énormes
Une trace complète de 1 000 rangs pendant dix minutes peut faire des centaines de gigaoctets et devenir inexploitable. Les remèdes :
- tracer une fenêtre courte et représentative, pas toute l'exécution ;
- tracer un sous-ensemble de rangs ;
- utiliser d'abord un profil (Cube, mpiP) et ne tracer que la phase suspecte ;
- filtrer les fonctions instrumentées.
Commencez toujours par le profil. La trace est l'outil du second temps.
Niveau 6 · Les cas particuliers¶
Le faux partage : perf c2c record puis perf c2c report. Il identifie la
ligne de cache contestée, les adresses et les fonctions en cause. Il n'existe pas
d'équivalent aussi direct.
NUMA : numastat -p <pid> donne la répartition des pages par domaine.
numactl --hardware donne la matrice des distances.
Les entrées-sorties : Darshan, par préchargement de bibliothèque, sans recompilation. C'est l'outil décisif du chapitre Entrées-sorties.
La concurrence : ThreadSanitizer, Helgrind, Archer, et MUST pour les erreurs d'usage de MPI. Voir OpenMP et threads et MPI en profondeur.
L'énergie : perf stat -e power/energy-pkg/, /sys/class/powercap/,
nvidia-smi, IPMI, et Scaphandre pour l'export vers Prometheus. Voir
Énergie et efficacité.
L'analyse statique de boucle : llvm-mca, OSACA, uiCA. Ils prennent un
bloc d'assembleur et prédisent son débit en cycles, ce qui permet de savoir si un
noyau est limité par une unité d'exécution particulière.
La méthode, en six étapes¶
L'outil ne remplace pas la méthode. Voici celle qui fonctionne.
La boucle d'optimisation
1. Définir la métrique et la mesurer. Temps, GFLOPS, cellules par seconde. Une seule, celle qui compte.
2. Établir la borne. Roofline, ou performance d'une bibliothèque de référence. Sans borne, on ne sait pas s'il reste à gagner.
3. Localiser. Profil par échantillonnage. Les trois premières fonctions.
4. Diagnostiquer. Compteurs matériels sur la fonction chaude. Quelle est la cause : mémoire, vectorisation, dépendances, branchements, synchronisation ?
5. Formuler une hypothèse chiffrée, modifier une seule chose, mesurer, et valider numériquement.
6. Consigner. Une ligne dans le carnet : date, machine, compilateur, options, modification, métrique avant, métrique après, hash du commit.
Puis retourner à l'étape 3.
Le carnet de mesures¶
L'outil le plus important du chapitre, et il ne s'installe pas.
Un fichier par expérience, ou une base SQLite, ou même un CSV, contenant pour chaque mesure : la date, la machine, le compilateur et sa version, les options de compilation, les modules chargés, la taille du problème, le nombre de nœuds, de rangs et de threads, le hash du commit, la métrique, le nombre de répétitions, et la variance.
Pourquoi c'est capital. Dans six mois, vous ne vous souviendrez d'aucun de ces paramètres, et une mesure sans son contexte est inutilisable. Dans trois ans, votre carnet sera la partie la plus précieuse de votre travail : il contiendra la caractérisation de toutes les machines que vous aurez utilisées et l'historique de toutes les optimisations que vous aurez tentées, y compris celles qui ont échoué — qui sont les plus instructives.
Exercices¶
E1 · ★ ⏱ 2 h — Le premier flame graph. Installer perf et les scripts de
flame graph, profiler un programme de plus de mille lignes, produire le
graphique, et rédiger un diagnostic d'une demi-page.
E2 · ★★ ⏱ 3 h — LIKWID sur trois noyaux. Mesurer avec likwid-perfctr les
groupes FLOPS_DP, MEM_DP et L3CACHE sur un DAXPY, un DGEMM et un SpMV.
Remplir un tableau des métriques dérivées et en déduire le régime de chacun.
Comparer au calcul manuel d'intensité arithmétique du chapitre
Modèles de performance.
E3 · ★★ ⏱ 2 h — Le roofline automatique. Si Intel Advisor est disponible, produire le roofline d'un code et comparer au roofline tracé à la main. Les deux doivent concorder ; l'écart éventuel est instructif.
E4 · ★★★ ⏱ 4 h — mpiP puis Score-P. Sur un code MPI qui passe mal à l'échelle, commencer par mpiP pour identifier la fonction MPI coûteuse, puis produire une trace Score-P d'une fenêtre courte et l'analyser dans Vampir ou Cube. Identifier le chemin critique et le déséquilibre.
E5 · ★★★ ⏱ 3 h — perf c2c. Reproduire un cas de faux partage, le
diagnostiquer avec perf c2c, lire le rapport, corriger, et vérifier la
disparition du symptôme dans le rapport.
E6 · ★★★ ⏱ 4 h — Nsight sur un code GPU. Profiler un code GPU avec Nsight Systems pour la chronologie, identifier les périodes où le GPU est inactif, puis Nsight Compute sur le noyau dominant pour obtenir occupancy, débits et roofline. Rédiger un diagnostic.
E7 · ★★★ ⏱ 4 h — Le carnet, mis en place. Construire un script qui, appelé autour d'une exécution, collecte automatiquement toutes les métadonnées (machine, compilateur, modules, hash Git, paramètres, métrique) et ajoute une ligne dans une base SQLite. Puis un petit script d'interrogation qui produit les courbes. C'est une infrastructure qui vous servira des années. Lien avec le projet de ITIC23.
E8 · ★★★★ ⏱ 5 h — La chasse à l'aveugle. Demander à un camarade de dégrader volontairement la performance d'un code (ajouter du faux partage, casser l'alignement, désactiver la vectorisation, changer l'ordre des boucles, sur-abonner les threads) sans vous dire lequel. Diagnostiquer avec les outils, en vous chronométrant. Puis inverser les rôles. C'est le meilleur entraînement possible aux quarante-huit heures d'une compétition.
Ressources¶
Priorité 1 :
- Brendan Gregg, Systems Performance, 2ᵉ éd., et son site
(
brendangregg.com). La méthodologie de diagnostic, et les flame graphs dont il est l'inventeur. Le site contient une page par outil. - La documentation de LIKWID (
github.com/RRZE-HPC/likwid), avec le wiki et la liste des groupes de compteurs. - Hager & Wellein, chapitre sur l'analyse de performance : la méthode avant les outils.
Priorité 2 :
- La documentation
perf(perfwiki.github.io), et les perf examples de Brendan Gregg. - Intel VTune et Intel Advisor, guides d'utilisation.
- Score-P (
score-p.org), Scalasca, Cube, Vampir. - Extrae et Paraver (
tools.bsc.es), avec la méthodologie d'analyse du BSC. - MAQAO (
maqao.org) et son guide d'interprétation des rapports.
Priorité 3 :
- HPCToolkit (
hpctoolkit.org), TAU (tau.uoregon.edu), mpiP. - Darshan (
wordpress.cels.anl.gov/darshan/). llvm-mca, OSACA, uiCA pour l'analyse statique.- Hoefler & Belli, « Scientific Benchmarking of Parallel Computing Systems », SC 2015 : les règles de présentation des mesures.
À retenir¶
Les cinq outils à savoir utiliser de mémoire
perf record+perf reportou un flame graph : où passe le temps.likwid-perfctr: pourquoi c'est lent, par les compteurs matériels.mpiP: le profil MPI, léger, avant toute trace.Nsight Systems: ce que fait le GPU, et quand il attend.Darshan: comment le code écrit ses fichiers.
Et le sixième, qui ne s'installe pas : le carnet de mesures.
Et la règle de méthode
Borne, localiser, diagnostiquer, hypothèse, une modification, mesurer, valider, consigner. Dans cet ordre, toujours.
Chapitre suivant : Solveurs et algèbre linéaire.