Votre GPU est « à 95 % d’utilisation », le tableau de bord est vert, et le client se plaint toujours de chutes d’images ou de pics de latence d’inférence.
Bienvenue dans la partie production où les moyennes mentent et où les goulots d’étranglement se cachent en pleine vue.
ROPs, TMUs, SMs et CUs sont les parties du corps au nom ennuyeux qui déterminent si votre GPU sprinte, boîte ou attend la mémoire comme s’il était coincé derrière un chariot élévateur lent.
Voici la carte à utiliser quand les chiffres ne collent pas.
Un modèle mental qui survit aux charges réelles
Il y a deux modes d’échec courants quand on parle de « performance GPU » :
(1) traiter le GPU comme un unique chiffre (utilisation), et
(2) traiter les composants GPU comme des mots magiques (« plus de SMs règle ça »).
Les deux conduisent à des erreurs coûteuses.
Utilisez plutôt ce modèle mental : le GPU est une chaîne de fabrication spécialisée reliée par des routes partagées.
Les SMs/CUs sont où la majeure partie des calculs a lieu ; les TMUs sont spécialistes des fetchs et du filtrage de textures (très présent en graphismes, parfois pertinent pour des opérations de type échantillonnage) ;
les ROPs sont l’étape où les pixels sont écrits avec mélange et tests depth/stencil.
Tout dépend de la bande passante mémoire, du comportement des caches et du driver/runtime qui doit garder les files alimentées.
En inférence ML, vous pouvez ignorer la plupart du temps les ROPs et TMUs — mais « la plupart du temps » n’est pas « toujours ».
Si vous effectuez du rendu, du compositing, de l’encodage/décodage vidéo ou exécutez des charges mixtes sur le même GPU, ces blocs deviennent sources de contention.
En graphismes, l’équilibre ROP/TMU compte tout le temps.
En termes opérationnels : les SMs/CUs sont vos cœurs CPU, la bande passante mémoire est votre liaison réseau montante, les caches sont votre CDN, et les ROPs/TMUs sont des accélérateurs spécialisés.
Si vous ne regardez que « l’utilisation GPU », vous déclarez essentiellement un service sain parce que top montre 90 % CPU — puis vous vous demandez pourquoi la latence p99 flambe.
Une citation que j’ai vue tenir sur une décennie d’incidents : L’espoir n’est pas une stratégie.
— James Cameron.
Si vous voulez de la fiabilité, mesurez le système que vous avez réellement, pas celui que vous auriez souhaité acheter.
Anatomie du GPU : ROPs, TMUs, SMs, CUs (et les éléments oubliés)
SMs (NVIDIA) et CUs (AMD) : la force
NVIDIA les appelle Streaming Multiprocessors (SMs).
AMD les appelle Compute Units (CUs) (et sur les architectures récentes vous entendrez aussi parler de WGPs, ou workgroup processors, qui regroupent des CUs).
Ce sont les blocs qui exécutent la majorité du code shader et des kernels compute.
Chaque SM/CU contient plusieurs voies d’exécution (pensez « SIMD/SIMT lanes »), des registres, des ordonnanceurs et du stockage local (shared memory / LDS).
Ils sont conçus pour garder de nombreux threads « en vol » afin que lorsqu’un groupe se bloque (souvent sur la mémoire), un autre puisse tourner.
Traduction opérationnelle : les SMs/CUs sont des moteurs de débit. Ils aiment un travail parallèle et régulier et s’irritent quand on leur donne de petites tâches sérielles,
des branches lourdes ou des motifs d’accès mémoire qui ressemblent à des confettis éparpillés.
Deux conséquences pratiques :
- Occupancy (combien de warps/wavefronts peuvent être résidents) importe, mais ce n’est pas un objectif en soi. Parfois une moindre occupancy avec une meilleure localité mémoire gagne.
- La pression des registres est un tueur silencieux. Trop de registres par thread réduit l’occupancy et augmente les spills vers la mémoire locale, qui est essentiellement « la mémoire globale en manteau ».
TMUs : unités de texture (pas seulement pour les jeux)
Les Texture Mapping Units (TMUs) gèrent traditionnellement le calcul d’adresses de textures et le filtrage.
En graphismes, elles récupèrent les données de texture (souvent avec un cache spécialisé) et appliquent le filtrage (bilinéaire, trilineaire, anisotrope).
C’est leur travail quotidien.
En calcul intensif ML, vous pouvez ne jamais atteindre directement la limite des TMUs.
Mais les TMUs peuvent réapparaître indirectement lorsque :
- Vous faites du pré/post-traitement d’images sur le GPU.
- Vous utilisez des chemins d’échantillonnage accélérés matériellement via des API graphiques.
- Vous avez des charges mixtes — rendu plus calcul — partageant la même puce.
Si votre charge est lourde en fetchs de textures, les TMUs peuvent devenir un goulot même si la capacité shader/compute est abondante.
Dans ce cas « plus de SMs » ne vous sauvera pas.
ROPs : le service d’écriture
Les ROPs (Raster Operations Pipelines) sont responsables de prendre les données de pixels prêtes à être déposées dans un framebuffer et d’exécuter les étapes finales :
blending, tests depth/stencil et écriture en mémoire.
Si vous retenez une chose : les ROPs concernent l’écriture des pixels, et écrire des pixels est souvent gourmand en bande passante mémoire.
Les goulots ROP apparaissent dans les charges graphiques avec :
- Haute résolution (4K et plus)
- Beaucoup d’overdraw
- Blending intensif (transparence, post-traitement)
- MSAA (plus d’échantillons écrits)
En compute-only, vous pourriez ne pas penser aux ROPs — et c’est acceptable — jusqu’à ce que vous exécutiez du compositing GPU, capture d’écran, bureau à distance ou overlays vidéo sur le même GPU.
Là, vous découvrez que les blocs « hors sujet » partageaient en fait la bande passante mémoire et les caches avec votre kernel « important ».
Sous-système mémoire : la partie qui ruine votre journée
Le sous-système mémoire GPU est la combinaison de HBM/GDDR, contrôleurs mémoire, cache L2 et interconnexions qui déplacent les données entre les SMs/CUs et la VRAM.
C’est fréquemment le véritable goulot, et il se fiche de vos TFLOPS théoriques.
Si vos kernels sont limités par la mémoire, ajouter du compute n’aidera pas.
Si vous êtes limité par la bande passante, la solution gagnante est généralement l’une des suivantes :
meilleure localité mémoire, moins d’octets déplacés, meilleure fusion, précision inférieure (lorsque sûr),
ou simplement utiliser un GPU avec plus de bande passante.
Ordonnanceurs, files d’attente et le problème « alimenté vs affamé »
Un GPU peut être en parfaite santé et pourtant sous-utilisé si l’hôte ne sait pas l’alimenter :
contention des threads CPU, goulot du GIL Python, transferts synchrones, petits batches, dataloaders lents ou un driver bloqué en sérialisation.
« Le GPU est à 20 % » n’est pas un problème GPU tant que vous ne l’avez pas prouvé.
Cores Tensor, RT et compagnons : blocs spécialisés qui changent les maths
Les GPU modernes ont des unités d’exécution spécialisées (Tensor Cores NVIDIA, unités matrice AMD, RT cores).
Ce ne sont pas des SMs/CUs, mais elles vivent à côté d’eux et peuvent modifier radicalement les caractéristiques de performance.
Elles sont aussi source fréquente de confusion : un kernel peut être lourd en calcul mais ne pas utiliser les unités matrice rapides à cause du dtype, du layout ou du choix de kernel.
Blague #1 : Un GPU, c’est comme une cuisine de restaurant — si le plongeur (bande passante mémoire) est lent, embaucher plus de chefs (SMs) ne fait que créer des piles plus hautes d’assiettes sales.
Faits intéressants et courte histoire (qui aide vraiment)
- Les ROPs précèdent le « GPU compute » tel qu’on le connaît. Ils étaient centraux quand les pipelines graphiques étaient plus à fonctions fixes, et écrire les pixels efficacement était primordial.
- Les premières ères du « shader model » ont fait de l’équilibre SM/TMU une stratégie produit. Les fournisseurs calibrèrent les puces pour des charges de jeu où fetch de texture + arithmétique avaient des rapports spécifiques.
- CUDA (ère 2007) a aidé à rebrander les SMs comme moteurs polyvalents. Soudain le même silicium qui dessinait des triangles faisait de l’algèbre linéaire et des simulations.
- La terminologie CU d’AMD vient d’un virage similaire. « Compute Unit » est un nom qui semble vouloir être ordonnancé par un compilateur, pas par un driver graphique.
- Les caches de texture ont influencé les motifs de calcul. Certains algorithmes utilisaient initialement des accès de type texture parce que ce chemin avait un comportement de cache que les loads généraux n’avaient pas alors.
- Le fillrate était autrefois une spec phare. Le débit pixel (souvent lié au nombre de ROPs et à la fréquence) comptait plus quand le shading était plus simple et que la bande passante de sortie était un mur dur.
- La bande passante mémoire a été la course aux armements de longue haleine. Les générations GDDR et HBM n’étaient pas des améliorations cosmétiques ; elles traitaient un goulot que les améliorations de compute dépassaient sans cesse.
- L’asynchronous compute et un meilleur ordonnancement ont changé le sens de « utilisation ». Un chiffre d’utilisation élevé peut masquer la contention des files ou un chevauchement sous-optimal entre copie/compute/graphismes.
- Les GPU modernes sont multi-locataires par conception. La préemption, le multi-instance GPU (MIG) et les fonctions de virtualisation existent parce que la production exigeait de l’isolation — pas parce que les joueurs l’ont demandé poliment.
Que mesurer et pourquoi : les métriques qui comptent
Si vous êtes responsable de la performance et de la fiabilité, vous devez savoir quel sous-système est saturé :
compute, bande passante mémoire, caches, PCIe/NVLink, pipeline graphique, ou la boucle d’alimentation hôte.
Le travail n’est pas « obtenir une forte utilisation GPU ». Le travail est « atteindre les SLOs à coût prévisible ».
Compute-bound vs memory-bound : arrêtez de deviner
Une charge compute-bound évolue avec :
plus de SMs/CUs, fréquences supérieures, meilleur mix d’instructions, meilleur usage des unités tensor/matrice.
Une charge memory-bound évolue avec :
plus de bande passante, meilleur taux de hit cache, meilleure coalescence, moins de lectures/écritures, fusion.
« Mais mon utilisation est élevée » est compatible avec les deux cas.
C’est pourquoi vous surveillez aussi le débit mémoire et les raisons de stall dans les profileurs.
ROPs et TMUs : quand ils comptent
Si vous exploitez des charges graphiques (fermes de rendu, VDI, game streaming, CAO), vous avez besoin de clarté par pipeline par image :
êtes-vous limité par le shading (SM/CU), le fetch/filtrage de texture (TMU), ou l’écriture/surblend (ROP) ?
Les symptômes diffèrent :
- Limite ROP : augmenter la résolution dégrade de façon disproportionnée ; le blending lourd tue ; la bande passante grimpe.
- Limite TMU : les scènes riches en textures s’effondrent même si l’utilisation ALU n’est pas maximale.
- Limite SM/CU : shaders complexes, heavy compute par pixel, ray marching, maths lourdes.
Les métriques opérationnelles piégeuses
- Limite de puissance / throttling : si le GPU est plafonné en puissance ou thermiquement limité, vos chiffres « attendus » sont fictifs.
- Erreurs ECC / remappage mémoire : les fonctionnalités de fiabilité peuvent changer les performances ; les erreurs peuvent dégrader le débit ou déclencher des retraits.
- Rejeu PCIe / bande passante : les transferts hôte→device peuvent dominer quand le batching est petit ou que vous faites trop de copies.
- Switching de contexte / contention multi-processus : plusieurs jobs peuvent se battre pour le cache, la bande passante mémoire et des tranches de temps d’exécution.
- Domaines d’horloge : l’horloge mémoire et l’horloge SM peuvent se comporter différemment sous limites.
Tâches pratiques : commandes, sorties et décisions (12+)
Ce sont des tâches « je suis de garde et j’ai besoin de réponses ». Chacune inclut : une commande, ce que signifie la sortie, et la décision que vous prenez.
Supposez Linux, outils NVIDIA quand applicable, et que vous avez le droit d’examiner la machine que vous payez.
(AMD a des outils comparables ; la logique est la même même si la commande diffère.)
Task 1: Confirm the GPU model, driver, and basic health
cr0x@server:~$ nvidia-smi
Tue Jan 13 12:44:10 2026
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14 Driver Version: 550.54.14 CUDA Version: 12.4 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 NVIDIA A10 On | 00000000:17:00.0 Off | 0 |
| 30% 62C P0 138W / 150W | 19750MiB / 24576MiB | 92% Default |
+-------------------------------+----------------------+----------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
|=============================================================================|
| 0 N/A N/A 18342 C python 19600MiB|
+-----------------------------------------------------------------------------+
Ce que cela signifie : Confirme la version du driver/CUDA, le modèle GPU, la consommation électrique, la température, l’utilisation mémoire, l’utilisation et quel processus possède la VRAM.
Décision : Si la mémoire est presque pleine, suspectez fragmentation/risque OOM ; si la puissance est au cap avec un état Perf élevé, vérifiez le throttling ; si GPU-Util est élevé mais le débit bas, creusez (mémoire ou stalls).
Task 2: Check for throttling reasons (power/thermal/voltage limits)
cr0x@server:~$ nvidia-smi -q -d PERFORMANCE | sed -n '1,120p'
==============NVSMI LOG==============
Timestamp : Tue Jan 13 12:44:17 2026
Driver Version : 550.54.14
CUDA Version : 12.4
Performance State : P0
Clocks Throttle Reasons
Idle : Not Active
Applications Clocks Setting : Not Active
SW Power Cap : Active
HW Slowdown : Not Active
HW Thermal Slowdown : Not Active
Sync Boost : Not Active
SW Thermal Slowdown : Not Active
Ce que cela signifie : « SW Power Cap: Active » signifie que vous atteignez la limite de puissance configurée ; les horloges peuvent être réduites pour s’y conformer.
Décision : Si vous contrôlez les thermals et l’enveloppe de puissance, augmentez la limite de puissance (dans les spécifications) ou améliorez le refroidissement. Si vous ne le pouvez pas, ajustez les attentes et la planification de capacité.
Task 3: Watch utilization, clocks, power, and memory in real time
cr0x@server:~$ nvidia-smi dmon -s pucvmt -d 1
# gpu pwr gtemp mtemp sm mem enc dec mclk pclk
# Idx W C C % % % % MHz MHz
0 149 69 - 78 94 0 0 5001 1710
0 150 70 - 79 95 0 0 5001 1710
0 150 70 - 80 95 0 0 5001 1710
Ce que cela signifie : Vous obtenez une vue en série temporelle. Si SM% est élevé mais mem% aussi, vous pouvez être memory-bound ou en train de thrasher les caches.
Décision : Si mem% est bloqué et la performance plate, concentrez-vous sur les octets déplacés (batching, fusion, précision). Si SM% est bas, concentrez-vous sur l’alimentation (CPU, dataloader, overhead de lancement).
Task 4: Check PCIe link width and speed (host feed limits)
cr0x@server:~$ nvidia-smi -q -d PCI | sed -n '1,120p'
PCI
Bus : 0x17
Device : 0x00
Domain : 0x0000
Bus Id : 00000000:17:00.0
PCIe Generation
Max : 4
Current : 3
Link Width
Max : 16x
Current : 8x
Ce que cela signifie : La carte supporte Gen4 x16 mais fonctionne actuellement en Gen3 x8. C’est une grosse réduction de la bande passante hôte-device.
Décision : Replacer la carte, changer de slot, vérifier les paramètres BIOS, vérifier les risers et la répartition des lanes sur la carte mère. Si votre charge est gourmande en transferts, cela peut être toute l’explication.
Task 5: Observe per-process GPU usage (multi-tenant contention)
cr0x@server:~$ nvidia-smi pmon -c 1
# gpu pid type sm mem enc dec command
# Idx # C/G % % % % name
0 18342 C 78 92 0 0 python
0 27711 C 12 7 0 0 python
Ce que cela signifie : Deux processus compute partagent le GPU. Le petit coûte toujours : switching de contexte, pression sur le cache et contention de la bande passante mémoire.
Décision : Si vous avez des SLOs de latence, isolez les charges (GPUs séparés, MIG, politiques d’ordonnancement). Si le but est le débit, la colocation peut être acceptable mais mesurez l’interférence.
Task 6: Check kernel driver logs for GPU resets or Xid errors
cr0x@server:~$ sudo journalctl -k --since "2 hours ago" | egrep -i "NVRM|Xid|gpu|pcie" | tail -n 20
Jan 13 11:52:03 server kernel: NVRM: Xid (PCI:0000:17:00): 31, pid=18342, Ch 0000002b, MMU Fault: ENGINE GRAPHICS GPCCLIENT_T1_0 faulted @ 0x7f3a0000
Jan 13 11:52:03 server kernel: NVRM: Xid (PCI:0000:17:00): 31, pid=18342, Ch 0000002b, MMU Fault: Fault type: UNBOUND_INST
Ce que cela signifie : Les erreurs Xid indiquent souvent des fautes de driver, matériel ou applicatives (accès mémoire invalides, PCIe défectueux, horloges instables).
Décision : Si les Xid se répètent : mettez l’hôte/GPU en quarantaine, reproduisez sous charge contrôlée, mettez à jour driver/firmware, exécutez des tests de stress et envisagez un RMA si le matériel est suspecté.
Task 7: Confirm CPU isn’t the real bottleneck (feeding the GPU)
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0 (server) 01/13/26 _x86_64_ (64 CPU)
12:44:43 PM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
12:44:44 PM all 92.1 0.0 7.1 0.0 0.0 0.3 0.0 0.5
12:44:44 PM 7 100.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
12:44:44 PM 8 100.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Ce que cela signifie : Les CPU sont saturés ; quelques cœurs sont épinglés. Si votre travail GPU est lancé depuis une boucle mono-thread, vous pouvez affamer le device.
Décision : Profilez la pipeline hôte : threads du dataloader, prétraitement, sérialisation, overhead Python. Augmentez le batch, utilisez des pipelines asynchrones ou déplacez le prétraitement sur le GPU.
Task 8: Check NUMA locality (PCIe devices hate cross-socket traffic)
cr0x@server:~$ nvidia-smi topo -m
GPU0 CPU Affinity NUMA Affinity
GPU0 X 0-31 0
Ce que cela signifie : GPU0 est attaché au nœud NUMA 0 ; l’affinité CPU recommandée est 0-31. Exécuter le thread d’alimentation sur l’autre socket ajoute de la latence et réduit la bande passante PCIe effective.
Décision : Pinner les threads CPU au bon nœud NUMA et allouer la mémoire hôte locale à ce nœud pour les transferts.
Task 9: Verify effective PCIe throughput during transfers
cr0x@server:~$ nvidia-smi dmon -s t -d 1
# gpu rxpci txpci
# Idx MB/s MB/s
0 5210 4980
0 5400 5102
0 5305 5055
Ce que cela signifie : Le débit RX/TX PCIe est autour de ~5 GB/s. Si vous attendiez un comportement Gen4 x16, vous sous-alimentez le device.
Décision : Réduisez les transferts (gardez les données plus longtemps sur le GPU, fusionnez les ops), augmentez la taille des batches, utilisez de la mémoire épinglée, et corrigez les problèmes de lien PCIe le cas échéant.
Task 10: Check GPU memory info and fragmentation risk
cr0x@server:~$ nvidia-smi --query-gpu=memory.total,memory.used,memory.free --format=csv
memory.total [MiB], memory.used [MiB], memory.free [MiB]
24576 MiB, 24010 MiB, 566 MiB
Ce que cela signifie : Vous êtes effectivement à court de VRAM. Même si vous « rentrez », la fragmentation de l’allocateur ou un pic soudain peut provoquer un OOM.
Décision : Réduisez modèle/batch, activez les optimisations mémoire (checkpointing d’activations où approprié), ou isolez cette charge de tout autre usage de la VRAM.
Task 11: Identify whether the GPU is doing graphics/display work (ROPs involved)
cr0x@server:~$ nvidia-smi --query-gpu=display_active,display_mode --format=csv
display_active, display_mode
Disabled, Disabled
Ce que cela signifie : Aucun écran n’est connecté et le mode affichage est désactivé. Bien : moins de surprises dues au compositing/effets de bureau.
Décision : Si l’affichage est actif sur un GPU de production compute, envisagez une configuration headless ou un GPU séparé pour l’affichage/VDI. L’usage mixte est la source de la « jitter mystère ».
Task 12: Check GPU clock settings (someone “optimized” you into a corner)
cr0x@server:~$ nvidia-smi -q -d CLOCK | sed -n '1,120p'
Clocks
Graphics : 1710 MHz
SM : 1710 MHz
Memory : 5001 MHz
Applications Clocks
Graphics : 1410 MHz
Memory : 5001 MHz
Ce que cela signifie : Les application clocks sont réglées plus bas que les horloges graphiques/SM de pointe. Cela peut brider les performances même si les thermals sont corrects.
Décision : Si c’est involontaire, réinitialisez les application clocks ou définissez-les explicitement pour correspondre à votre stratégie performance/puissance.
Task 13: Verify compute mode and persistence mode (multi-user behavior)
cr0x@server:~$ nvidia-smi --query-gpu=compute_mode,persistence_mode --format=csv
compute_mode, persistence_mode
Default, Enabled
Ce que cela signifie : Le mode compute par défaut permet plusieurs processus ; la persistence est activée pour éviter des overheads d’initialisation répétés et peut réduire la latence du premier job.
Décision : Pour une isolation stricte, envisagez le mode Exclusive Process (là où approprié). Gardez la persistence activée pour un comportement stable en production.
Task 14: Confirm hugepages/IOMMU aren’t sabotaging DMA (host-level checks)
cr0x@server:~$ dmesg | egrep -i "iommu|DMAR|vfio" | tail -n 10
[ 0.612345] DMAR: IOMMU enabled
[ 0.612900] DMAR: Intel(R) Virtualization Technology for Directed I/O
Ce que cela signifie : IOMMU est activé. C’est acceptable, mais des mauvaises configurations peuvent causer un overhead ou des limites de mapping dans certains setups.
Décision : Si vous observez une latence de transfert inhabituelle ou des erreurs de mapping, validez les réglages IOMMU pour votre environnement (surtout en passthrough/virtualisation).
Task 15: Quick-and-dirty “is this memory-bound?” check using observed throughput
cr0x@server:~$ nvidia-smi --query-gpu=utilization.gpu,utilization.memory --format=csv -l 1
utilization.gpu [%], utilization.memory [%]
91 %, 96 %
92 %, 97 %
90 %, 96 %
Ce que cela signifie : Une forte utilisation mémoire accompagnée d’une forte utilisation GPU pointe souvent vers des kernels memory-bound ou un trafic mémoire important (y compris des spills).
Décision : Passez au profiling : vérifiez le débit mémoire, les taux de hit cache et les raisons de stall au niveau kernel. Ne perdez pas de temps à tuner l’arithmétique d’abord.
Mode opératoire de diagnostic rapide : trouver le goulot en minutes
Voici le chemin « ne vous perdez pas dans les captures du profileur ». Il est optimisé pour le triage en production.
L’objectif : identifier si vous êtes limité par l’alimentation, le compute, la bande passante mémoire, le pipeline graphique (TMU/ROP) ou le throttling/les fautes.
Premier : sanity et santé (30–60 secondes)
- Exécutez
nvidia-smi. Vérifiez : erreurs, températures, puissance, utilisation mémoire, processus actifs. - Vérifiez les logs noyau pour Xid/événements de reset (
journalctl -k). - Vérifiez les raisons de throttling (
nvidia-smi -q -d PERFORMANCE).
Si vous trouvez des resets, des pics ECC ou des Xid répétés, arrêtez de chasser la performance. Vous déboguez la fiabilité maintenant.
Deuxième : le GPU est-il alimenté ? (2–3 minutes)
- Regardez la saturation CPU (
mpstat/top). - Vérifiez l’état du lien PCIe (Gen/width) et le débit PCIe (
nvidia-smi -q -d PCI,nvidia-smi dmon -s t). - Vérifiez l’affinité NUMA (
nvidia-smi topo -m).
Si le CPU est épuisé ou si le PCIe est rétrogradé (surprise Gen3 x8), vous avez un problème de plateforme, pas un problème de kernel.
Troisième : classer le goulot par comportement (5–10 minutes)
- Compute-bound : SM busy élevé, mem util modérée ; évolue avec les horloges ; s’améliore avec les tensor cores activés.
- Memory-bound : mem util élevée, performance plate avec des horloges SM plus élevées, sensible à la taille de batch et à la fusion.
- TMU/texture-bound (graphisme) : scènes riches en textures s’effondrent ; les changements d’échantillonnage/filtrage impactent plus que les maths du shader.
- ROP/output-bound (graphisme) : résolution et blending frappent fort ; les écritures de sortie dominent ; MSAA pénalise plus que prévu.
Votre outil suivant dépend de la classification. Si vous êtes compute-bound, optimisez les kernels et les maths. Si vous êtes memory-bound, réduisez le trafic et améliorez la localité.
Si vous êtes ROP/TMU-bound, ajustez les paramètres du pipeline de rendu ou choisissez un matériel avec un équilibre différent.
Erreurs courantes : symptôme → cause racine → correctif
1) « L’utilisation GPU est élevée mais le débit est faible »
Symptôme : GPU-Util 90 %+, mais fps ou inférences/sec décevants.
Cause racine : kernels limités par la mémoire, thrash de cache, spills de registres, ou contention d’autres processus.
Correctif : Confirmer l’utilisation mémoire et le comportement de bande passante ; profiler pour stalls/spills ; fusionner les kernels ; réduire la précision quand c’est sûr ; isoler les charges.
2) « L’utilisation GPU est faible mais la latence est élevée »
Symptôme : GPU-Util 10–30 %, pourtant la latence p99 est mauvaise.
Cause racine : goulot d’alimentation hôte (prétraitement CPU, petits batches, copies synchrones), ou overhead de lancement de kernel dominant.
Correctif : Augmenter la taille de batch, pipeline CPU/GPU, utiliser des transferts asynchrones, pinner les threads CPU sur des cœurs NUMA-locaux, et réduire les lancements GPU par requête.
3) « Les performances varient fortement entre serveurs identiques »
Symptôme : Même modèle GPU, un serveur est plus lent de 20–40 %.
Cause racine : training du lien PCIe à un Gen/width réduit, limites de puissance différentes, conditions thermiques ou paramètres BIOS divergents.
Correctif : Comparez nvidia-smi -q -d PCI et raisons de throttling ; standardisez firmware/BIOS, validez le refroidissement, corrigez l’allocation des lanes.
4) « Le rendu s’effondre en activant la transparence ou en augmentant la résolution »
Symptôme : Une scène va bien jusqu’à ce que vous ajoutiez de la transparence/post-traitement ; une résolution plus élevée fait chuter le FPS.
Cause racine : ROP/output et bande passante limités ; beaucoup de blending et d’overdraw augmentent le trafic d’écriture.
Correctif : Réduire l’overdraw, optimiser les passes de blending, envisager des buffers en précision plus faible si acceptable, et surveiller la bande passante mémoire. Un matériel avec plus de ROPs/bande passante aide.
5) « Les scènes riches en textures sont lentes même si les shaders ne sont pas complexes »
Symptôme : Math simple, mais la performance s’effondre avec textures haute résolution et filtrage.
Cause racine : TMU/texture-bound ; misses du cache de texture ; coût de l’anisotropic filtering.
Correctif : Ajuster les LODs de texture, réduire les niveaux de filtrage, compresser les textures correctement, réduire l’échantillonnage aléatoire, et choisir des SKUs GPU avec meilleures performances texture si nécessaire.
6) « Après une mise à jour du driver, tout est plus lent »
Symptôme : Même code, débit inférieur, comportement de puissance possiblement différent.
Cause racine : Différents clocks/power management par défaut, sélection de kernel modifiée, ou nouvelles mitigations de sécurité.
Correctif : Reverifier application clocks et power caps ; valider avec benchmarks contrôlés ; pinner des versions connues-stables quand vous avez besoin de performance déterministe.
7) « Nous avons acheté le GPU plus gros et obtenu peu d’amélioration »
Symptôme : Plus de SMs/TFLOPS, mais seulement un petit gain.
Cause racine : Vous étiez limité par la mémoire ou PCIe ; vous avez acheté du compute alors qu’il fallait bande passante ou une meilleure pipeline de données.
Correctif : Mesurez transfert et débit mémoire ; choisissez des GPU avec plus de bande passante (HBM), interconnexion plus rapide (NVLink), ou redesignez le chemin des données.
Blague #2 : La façon la plus facile de doubler la performance GPU est d’arrêter de lui envoyer le même tenseur trois fois — hélas, c’est plus courant qu’il ne devrait l’être.
Trois mini-histoires d’entreprise issues du terrain
Mini-histoire 1 : L’incident causé par une fausse hypothèse (les ROPs n’ont pas d’importance… jusqu’à ce qu’ils en aient)
Une entreprise exploitait une flotte GPU pour de l’analytique vidéo en temps réel : décodage, inférence, overlay de boîtes, et ré-encodage.
Ils considéraient la charge comme « principalement compute », donc le modèle de capacité était construit autour de l’utilisation SM et de la VRAM.
Tout semblait propre. C’était aussi faux.
Lors d’un lancement produit, les overlays sont devenus plus complexes : plus d’étiquettes, éléments UI avec alpha-blending et post-traitements supplémentaires.
Les graphes compute restaient confortables. Mais les flux clients ont commencé à perdre des images et la latence p95 a grimpé.
Les ingénieurs ont chassé les kernels, ajusté les tailles de batch, voire rétrogradé un modèle. Rien n’a tenu.
Le véritable coupable était la composition de sortie : le blending et l’écriture des images frappaient le sous-système mémoire et les étapes finales pixel.
En d’autres termes, le pipeline est devenu plus orienté ROP et gourmand en bande passante.
Le GPU était « occupé », mais pas de la manière supposée par le modèle.
La correction fut désespérément peu romantique :
ils ont réduit l’overdraw des overlays, changé la stratégie de composition pour minimiser les passes de blending, et réparti les responsabilités — compute sur un GPU, compositing/encode sur un autre sur les nœuds les plus chargés.
Ensuite, le système est redevenu prévisible à l’échelle. La leçon n’était pas « les ROPs sont importants ». La leçon était « les hypothèses coûtent cher ».
Mini-histoire 2 : L’optimisation qui s’est retournée contre eux (poursuivre l’occupancy jusqu’au fossé)
Une autre équipe avait un kernel CUDA plus lent que prévu. Quelqu’un a trouvé un article disant « maximisez l’occupancy ».
Ils ont refactoré le kernel pour utiliser moins de registres et augmenter l’occupancy. La capture du profileur avait l’air plus jolie.
En production, le débit a empiré.
Le changement a réduit l’usage des registres, mais a aussi augmenté le trafic mémoire global en recalculant des valeurs et en chargeant des intermédiaires.
Le kernel est passé de « modérément compute-bound » à « douleur memory-bound ».
L’occupancy a grimpé. La performance est tombée. Les graphiques ont menti parce qu’ils ne mesuraient pas la bonne limite.
La correction finale fut de renverser l’approche « occupancy à tout prix » :
accepter une occupancy plus faible, garder les valeurs critiques dans les registres, et restructurer les accès mémoire pour plus de coalescence.
Ils ont aussi fusionné deux kernels adjacents pour éviter d’écrire un tenseur intermédiaire en VRAM.
L’occupancy semblait pire ; le débit s’est amélioré matériellement.
Le suivi opérationnel fut encore plus précieux : ils ont ajouté une porte de performance à la CI qui exécutait des kernels représentatifs et comparait le débit mémoire et les distributions de temps d’exécution.
Le prochain changement « malin » a été attrapé avant la production.
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise (standardiser PCIe et alimentation)
Une équipe plateforme exploitait des serveurs GPU mixtes achetés à différentes vagues d’approvisionnement.
Même modèle GPU sur papier, mais cartes mères, versions BIOS et flux d’air de châssis différents.
Ils avaient une règle peu glamour : chaque nœud devait passer un test d’acceptation « lanes et horloges » avant d’entrer dans le cluster.
Le test était ennuyeux : vérifier PCIe Gen/width, exécuter un court benchmark de transfert, confirmer la limite de puissance, confirmer les horloges en charge soutenue, confirmer l’absence d’erreurs Xid.
C’est le genre de chose que les gens appellent bureaucratie jusqu’à ce qu’ils soient de garde à 3 h du matin.
Un week-end, un lot de nœuds est arrivé avec une configuration de riser qui entraînait silencieusement la carte à une largeur de lien réduite.
Sans la porte, ces nœuds auraient été ajoutés à la piscine et auraient provoqué des jobs lents aléatoires, des timeouts intermittents et un flux sans fin de tickets de performance.
À la place, la porte les a échoués immédiatement. Ils ont été corrigés avant que les clients ne les voient.
Le gain n’était pas « nous avons attrapé un bug ». Le gain était de prévenir une classe entière de comportements instables d’entrer dans le système.
La production adore les vérifications ennuyeuses et répétables.
Listes de contrôle / plan étape par étape
Checklist A : Quand quelqu’un dit « le GPU est lent »
- Identifiez le type de charge : compute-only, graphics-only, ou mixte (decode/encode/display/compositor inclus).
- Vérifiez la santé GPU :
nvidia-smi, versions du driver, températures, puissance, erreurs. - Vérifiez les raisons de throttling : power cap, ralentissement thermique, application clocks.
- Confirmez le lien plateforme : PCIe Gen/width, localité NUMA, débit PCIe sous charge.
- Vérifiez la contention multi-tenant : usage par processus ; confirmez hypothèses d’ordonnancement/isolation.
- Classez le goulot : compute-bound vs memory-bound vs feed-bound ; pour le graphisme considérez le comportement TMU/ROP.
- Ce n’est qu’ensuite que vous ouvrez le profileur — et allez-y avec une hypothèse.
Checklist B : Avant d’acheter du matériel ou de redimensionner un cluster
- Mesurez le goulot actuel (pas seulement l’utilisation).
- Si memory-bound, priorisez bande passante/cache et changements logiciels avant plus de compute.
- Si transfer-bound, priorisez interconnexion et localité des données (PCIe Gen, NVLink, pinning NUMA).
- Si ROP/TMU-bound (graphisme), choisissez des SKUs avec l’équilibre approprié ; n’achetez pas du compute que vous ne pouvez pas alimenter ou écrire.
- Prévoyez l’isolation : MIG, GPUs dédiés par service sensible à la latence, ou au moins enforcement côté cgroup et ordonnanceur.
- Standardisez les tests d’acceptation : largeur de lane, horloges sous charge, paramètres de power cap, logs d’erreur propres.
Checklist C : Boucle sûre d’optimisation des performances (celle qui n’engendre pas d’incidents)
- Choisissez une charge représentative. Pas un microbenchmark sauf si c’est votre réalité de production.
- Enregistrez les baselines : débit, distribution de latence, puissance, températures, utilisation mémoire, débit PCIe.
- Changez une chose. Une seule.
- Remesurez et comparez des distributions, pas seulement des moyennes.
- Avancez uniquement si vous comprenez pourquoi ça s’est amélioré et pouvez expliquer les nouveaux modes de défaillance.
- Ajoutez une porte de régression si le changement compte (job CI, canary, ou run perf nocturne).
FAQ
1) Quelle est la définition la plus simple des SMs et CUs ?
Ce sont les blocs d’exécution principaux qui lancent des threads parallèles pour les shaders et les kernels compute.
NVIDIA les appelle SMs ; AMD les appelle CUs. Des internals différents, rôle similaire : effectuer les calculs et masquer la latence avec beaucoup de travail parallèle.
2) « CUDA cores » sont-ils la même chose que les SMs ?
Non. « CUDA cores » est un comptage marketing-friendly des voies ALU scalaires à travers tous les SMs.
Un SM est l’unité qui ordonnance et gère le travail ; il contient plusieurs unités d’exécution, registres et mémoire partagée.
3) Que font réellement les TMUs, et pourquoi s’en soucier ?
Les TMUs récupèrent les données de texture et appliquent le filtrage efficacement. En graphismes, les limites TMU sont réelles et visibles.
En compute, elles comptent lorsque votre charge utilise des chemins d’échantillonnage texture ou quand des charges mixtes provoquent de la contention pour la mémoire/le cache.
4) Que font les ROPs, et quand sont-ils un goulot ?
Les ROPs gèrent les opérations pixel finales : blending, depth/stencil et écriture des pixels dans le framebuffer.
Ils deviennent un goulot quand les écritures de sortie dominent : haute résolution, blending intensif, beaucoup d’overdraw, MSAA, ou scénarios limités par la bande passante.
5) Pourquoi augmenter la résolution nuit parfois autant aux performances ?
Plus de pixels signifie plus de travail dans les étapes tardives du pipeline et plus de trafic mémoire.
Si vous êtes ROP/bande passante limité, doubler le nombre de pixels peut écraser le FPS même si le compute n’est pas saturé.
6) Pourquoi l’utilisation GPU est faible alors que mon programme « utilise le GPU » ?
Raisons courantes : goulot CPU pré-traitement, petites tailles de batch, copies hôte-device synchrones, overhead de lancement de kernel, ou attente I/O.
Une faible utilisation signifie souvent que le GPU est inactif en attente de travail.
7) Une haute occupancy est-elle toujours bonne ?
Non. L’occupancy est un outil pour masquer la latence, pas un trophée.
Pour certains kernels, une occupancy plus élevée augmente le trafic mémoire ou force des spills. Le critère gagnant est le débit et la latence en charge réelle, pas une métrique unique.
8) Comment les ROPs/TMUs se rapportent à l’inférence ML ?
Habituellement ils ne le font pas — jusqu’à ce que vous exécutiez du pré/post-traitement, composition ou vidéos sur le même GPU.
Aussi, tout ce qui augmente la pression sur la bande passante mémoire peut indirectement nuire au débit ML, même si les ROPs/TMUs ne sont pas utilisés directement.
9) Quelle est la manière la plus rapide de savoir si je suis memory-bound ?
Surveillez l’utilisation mémoire et le débit sous charge, puis changez quelque chose qui devrait augmenter le compute (comme les horloges SM ou un SKU compute plus rapide).
Si la performance change peu, vous êtes probablement memory-bound. Confirmez ensuite avec le profiling des stalls/bande passante mémoire.
10) Dois-je partager des GPUs entre services en production ?
Seulement si vous pouvez tolérer l’interférence et que vous la mesurez.
Pour des charges sensibles à la latence, isolez avec des GPUs dédiés ou MIG/partitionnement. « Ça a marché en staging » n’est pas une politique d’ordonnancement.
Conclusion : étapes pratiques suivantes
ROPs, TMUs, SMs et CUs ne sont pas des anecdotes. Ce sont la carte des endroits où votre travail peut se coincer.
Quand vous diagnostiquez par étape de pipeline — alimentation, compute, mémoire, sortie — vous arrêtez de deviner et commencez à réparer.
Prochaines étapes qui rapportent immédiatement :
- Ajoutez un test d’acceptation léger pour nœud GPU : PCIe Gen/width, horloges soutenues sous charge, pas de Xids, puissance/températures stables.
- Instrumentez vos services avec débit et distributions de latence en parallèle des métriques GPU/CPU/PCIe. Les moyennes sont mignonnes. Le p99 paie votre salaire.
- Quand la performance régresse, exécutez le mode opératoire de diagnostic rapide avant de toucher au code. La moitié des « problèmes GPU » sont des problèmes de plateforme et pipeline.
- Pour les charges graphiques/mixtes, considérez explicitement TMU/ROP et contraintes de bande passante. Si vous ne modélisez pas le coût de sortie, il vous modélisera.