Votre CPU s’ennuie. Pas parce qu’il manque de cœurs, mais parce qu’il ne reçoit pas assez de données. Vous lancez plus de threads, la file d’exécution grossit et le p99 empire.
Quelque part en dessous, la bande passante mémoire est le vrai goulot—transformant silencieusement votre « flotte de calcul » en une salle d’attente coûteuse.
La High Bandwidth Memory (HBM) sur les CPU est la réponse industrielle, brute et pragmatique : si les données n’arrivent pas assez vite vers les cœurs, on met un peu de mémoire dans le package et on élargit les canaux.
Ça ressemble à une victoire simple. Ce ne l’est pas. Cela change les modes de défaillance, l’optimisation, la planification de capacité et la lecture des graphes de performance à 2 h du matin.
Ce que change réellement l’HBM sur un CPU
Définissons ce dont il s’agit : HBM est de la DRAM empilée (plusieurs dies empilés verticalement) connectée au package processeur via une interface extrêmement large.
Ce n’est pas de la mémoire magique. C’est de la DRAM avec un meilleur packaging, des bus plus larges et un profil coût/GB différent.
Quand l’HBM est « sur » un CPU—généralement sur le même package, reliée par des interconnexions courtes—trois choses changent d’une manière perceptible pour les opérateurs :
1) La bande passante devient moins rare (jusqu’à la prochaine limite)
Les canaux DDR traditionnels se sont améliorés, mais pas au rythme des nombres de cœurs et des unités vectorielles. L’HBM fournit beaucoup plus de bande passante agrégée, ce qui aide les charges limitées par la bande passante : analytics en streaming, algèbre linéaire creuse, scans mémoire volumineux, recherche vectorielle et de nombreux patterns d’inférence IA qui ne tiennent pas bien dans les caches.
2) La capacité devient plus précieuse
La capacité HBM par socket est généralement bien plus petite que la capacité DDR. Vous échangez des « GB bon marché » contre des « GB très rapides ».
Cela vous oblige à des décisions de tiering : ce qui vit dans l’HBM, ce qui déborde vers le DDR et ce qui est renvoyé vers le stockage.
3) Le NUMA devient plus étrange et plus important
Le système d’exploitation expose souvent l’HBM comme un nœud NUMA distinct (ou plusieurs nœuds). C’est bien : c’est visible et contrôlable.
C’est aussi problématique : vous pouvez maintenant placer accidentellement vos pages chaudes sur le niveau lent pendant que le niveau rapide reste inactif, comme des CPU réservés dans un cluster Kubernetes que personne n’a demandé.
Pourquoi cela arrive maintenant (et pourquoi le DDR n’est pas en « échec »)
Le DDR n’est pas cassé. Il subit simplement la physique et l’économie. Les broches coûtent cher, le routage est difficile et l’intégrité du signal est un hobby pour ceux qui aiment la douleur. Pendant ce temps, les CPU gagnent en cœurs, SIMD plus larges et accélérateurs qui peuvent ingérer des données à des débits que le DDR ne peut pas toujours fournir.
Les technologies d’emballage se sont suffisamment améliorées pour que rapprocher la mémoire soit non seulement possible, mais commercialement sensé pour certains marchés :
HPC, IA, analytics et certains services sensibles à la latence où « ajouter des nœuds » n’est plus une phrase respectable.
Récapitulatif opérationnel : l’HBM sur CPU n’est pas un remplacement de la mémoire capacitaire. C’est une reconnaissance que la bande passante est une ressource de première classe.
Traitez-la comme vous traitez les IOPS sur un hôte de base de données : mesurable, épuisable et facile à gaspiller.
Faits et historique intéressants pour les réunions de planification
- Fait 1 : Le problème du « mur mémoire »—la vitesse du CPU dépassant la vitesse mémoire—a été discuté depuis les années 1990, et il n’a jamais cessé d’être vrai ; il a juste été mieux caché par les caches.
- Fait 2 : L’HBM est de la « DRAM 3D empilée » connectée via des through-silicon vias (TSV), ce qui explique pourquoi elle peut exposer une interface très large sans cauchemar de connecteurs.
- Fait 3 : Les GPU ont adopté l’HBM tôt parce que leur débit rend les pénuries de bande passante douloureuses ; les CPU sont arrivés plus tard en partie parce qu’ils avaient besoin de plus grandes capacités et d’une compatibilité workload plus large.
- Fait 4 : Les systèmes mémoire à plusieurs niveaux ne sont pas nouveaux—les mainframes et certains systèmes vectoriels utilisaient des hiérarchies mémoire explicites bien avant que les serveurs modernes prétendent que tout est plat.
- Fait 5 : Les premières expériences de « mémoire sur package » ont montré un thème récurrent : les gains de performance étaient réels, mais l’écosystème logiciel a mis des années à rattraper l’allocation et le réglage.
- Fait 6 : Linux moderne peut exposer de la mémoire hétérogène comme des nœuds NUMA, permettant le contrôle de politique via
numactlet des stratégies mémoire ; la partie difficile est de choisir des politiques qui ne s’effondrent pas sous charge. - Fait 7 : Les charges lourdes en bande passante ressemblent souvent à « CPU à 40 % d’utilisation », ce qui trompe les équipes qui scale le compute au lieu de corriger le placement mémoire.
- Fait 8 : Les choix d’emballage et de mémoire sont de plus en plus liés à l’énergie : déplacer des bits sur une carte coûte plus d’énergie que de les déplacer à l’intérieur d’un package.
- Fait 9 : L’industrie pousse aussi CXL pour l’expansion et la mise en pool de mémoire ; HBM et CXL sont moins concurrents que des réponses différentes au dilemme « rapide » vs « volumineux ».
La mémoire deviendra-t-elle partie intégrante du package CPU ?
Pour certains niveaux de calcul, oui—et pas comme un projet de foire scientifique. Vous verrez plus de CPU livrés avec une certaine quantité de mémoire haute bande passante sur package, car cela résout un problème précis :
alimenter beaucoup de compute sans transformer chaque carte mère en scène de crime pour le signal haute vitesse.
Mais « la mémoire devient partie du package » ne veut pas dire « les DIMM disparaissent ». Cela signifie que l’histoire mémoire devient stratifiée :
- HBM sur package : capacité modérée, énorme bande passante, relativement efficace en énergie par bit déplacé, coûteux par GB.
- DDR hors package : grande capacité, bonne performance générale, moins cher par GB, limité par le nombre de canaux et contraintes carte.
- Mémoire hors hôte ou mise en pool (CXL) : grande et flexible, mais latence supérieure ; idéale pour consolidation, pas pour alimenter des unités vectorielles à plein régime.
Du point de vue système : ce n’est pas tant « la mémoire a déménagé dans le CPU » que « le CPU a grandi un garde-manger privé ». Vous avez toujours besoin de l’entrepôt (DDR).
Blague n°1 : Si vous avez déjà vu un CPU se bloquer sur la mémoire, vous savez déjà que le composant le plus rapide du serveur est la facture.
Latence vs bande passante : la confusion fréquente
Les opérateurs aiment un seul chiffre. La mémoire refuse de coopérer. L’argument principal de l’HBM est la bande passante, pas nécessairement une latence inférieure au DDR dans tous les cas.
En pratique, l’image de la latence dépend de l’implémentation, des contrôleurs mémoire et de la façon dont l’OS mappe les pages.
Deux schémas de défaillance apparaissent régulièrement :
Charges liées à la bande passante qui semblent CPU-bound
Le pipeline CPU est occupé « à faire quelque chose », mais les instructions retraitées par cycle sont faibles. Vous ajoutez des cœurs et ne voyez presque aucune augmentation de débit.
L’HBM peut corriger cela—si les données chaudes se trouvent dans l’HBM. Si ce n’est pas le cas, vous avez acheté une voiture de course et mis de l’essence de tondeuse.
Charges sensibles à la latence qui bénéficient peu
Si votre charge est une chaîne de parcours de pointeurs dépendants, un code très branché ou de petits accès aléatoires, la bande passante n’est pas le facteur limitant.
Vous pouvez constater une amélioration minimale. Parfois une régression si les politiques mémoire poussent des pages critiques dans un niveau « haute bande passante » avec une latence effective pire sous contention.
La phrase à retenir : HBM corrige « pas assez d’octets par seconde », pas « trop de nanosecondes par accès ».
Une citation, parce que c’est le cœur du sujet : « Le code le plus rapide est celui qui ne s’exécute pas. » —Jeff Atwood. Si l’HBM vous fait ignorer le gaspillage algorithmique, vous perdrez quand même.
Modèles de tiering HBM+DDR : cache, nœud NUMA ou allocation explicite
Les vendeurs et plateformes présentent l’HBM de plusieurs façons. Votre posture opérationnelle change selon ce que vous avez.
Ne devinez pas. Vérifiez ce que l’OS expose.
Modèle A : HBM en cache transparent
Le système utilise l’HBM comme cache pour le DDR. Cela réduit le contrôle de l’opérateur et réduit la faute de l’opérateur—jusqu’à ce que ça ne marche plus.
L’avantage est la simplicité ; l’inconvénient est l’imprévisibilité sous charges mixtes et le problème classique de cache : ce qui est chaud pour une charge évince ce qui est chaud pour une autre.
Modèle B : HBM comme nœud NUMA distinct (« mode flat »)
Linux voit l’HBM comme des nœuds NUMA séparés. C’est le mode convivial pour l’opérateur car vous pouvez lier des processus, définir la politique mémoire et diagnostiquer le placement.
C’est aussi le mode où vous pouvez créer votre propre incident avec un simple copier-coller de numactl.
Modèle C : placement géré par l’application
Certains runtimes, allocateurs ou frameworks peuvent diriger les allocations vers des nœuds mémoire spécifiques.
C’est le plus puissant et le moins indulgent, car la correction inclut maintenant « est-ce que votre allocateur fait toujours ce que vous pensez qu’il fait en présence de fragmentation ».
Blague n°2 : Le tiering mémoire, c’est comme le placement des bureaux—tout le monde ~est d’accord que ça doit être juste jusqu’à ce que les sièges près des fenêtres arrivent.
Quelles charges bénéficient réellement (et lesquelles non)
Très bonnes candidates
- Scans en streaming et analytics : scans columnaires, pipelines de décompression, transformations ETL qui lisent beaucoup d’octets et effectuent un travail modéré par octet.
- Recherche vectorielle et opérations sur embeddings : surtout quand l’ensemble de travail est plus grand que le cache et que l’accès est semi-structuré.
- Noyaux scientifiques/HPC : codes stencil, FFT, variantes d’algèbre linéaire et tout ce qui s’est historiquement plaint de la bande passante mémoire.
- Inférence IA sur CPU (cas sélectionnés) : pas parce que le CPU bat le GPU, mais parce que la bande passante peut être le facteur limitant quand le modèle ou les activations sont gourmands en mémoire.
Candidats marginaux
- Microservices à faible latence : si vous avez déjà beaucoup de hits L3 et que le réseau/sérialisation dominent, l’HBM ne vous sauvera pas.
- Recherches aléatoires à petites clés : le parcours de pointeurs touche plutôt les limites de latence et le comportement des caches plus que la bande passante brute.
- Systèmes liés au disque : si vous attendez le stockage, réparez le stockage. L’HBM ne rendra pas un SSD lent honteux.
Mauvaises candidates
- Tout ce qui requiert une énorme RAM par hôte mais pas la bande passante : la capacité HBM est trop petite ; vous finirez de toute façon sur DDR.
- Machines multi-tenant non contrôlées : si vous ne pouvez pas épingler ou contrôler les politiques mémoire, le niveau rapide devient une tragédie partagée.
Implications SRE : nouveaux goulots, nouveaux mensonges, nouveaux tableaux de bord
L’HBM ne supprime pas les goulots. Il les déplace. Quand vous augmentez la bande passante mémoire, vous exposez souvent le limiteur suivant :
exécution des cœurs, trafic de cohérence de cache, liens inter-socket, PCIe, ou simplement un verrou dans votre code que personne n’a touché parce que « ça allait ».
Changements de planification de capacité
Vous planifiez désormais deux capacités : la RAM totale (DDR+HBM) et la « RAM rapide » (HBM).
Un service peut être « dans les limites mémoire » et pourtant être « hors HBM », ce qui ressemble à une régression de performance sans saturation évidente des ressources.
Changements d’observabilité
Vous avez besoin de l’utilisation mémoire par nœud NUMA, de compteurs de bande passante (uncore/IMC) et des statistiques de migration de pages si votre plateforme les supporte.
L’utilisation CPU n’est plus même de près suffisante.
Changements de fiabilité
Plus de complexité d’emballage signifie des surfaces de défaillance différentes : thermiques sur package, différences de rapport ECC et quirks firmware.
Aussi : un hôte peut être « sain » et pourtant « mal placé », où les pages chaudes se trouvent sur le DDR parce que le processus a démarré avant l’application de la politique.
Guide de diagnostic rapide
Utilisez ceci quand une charge est plus lente que prévu sur un hôte CPU compatible HBM. L’objectif est de localiser le goulot en quelques minutes, pas d’écrire une thèse.
Première étape : vérifier ce que le système expose
- L’HBM est-il présent et visible comme nœuds NUMA, ou est-il configuré en mode cache ?
- La charge alloue-t-elle réellement depuis l’HBM, ou « tourne-t-elle juste sur le CPU qui a de l’HBM à proximité » ?
Deuxième étape : décider si vous êtes limité par la bande passante
- Vérifiez les compteurs de bande passante mémoire et les misses de LLC.
- Cherchez un IPC faible avec de nombreux stalls mémoire.
- Confirmez que l’ajout de cœurs n’augmente pas le débit.
Troisième étape : confirmer le placement et la politique
- Vérifiez l’utilisation mémoire par nœud NUMA pour le processus.
- Vérifiez si le NUMA balancing automatique a migré des pages hors de l’HBM.
- Vérifiez l’affinité : épingler les CPU sans lier la mémoire n’est qu’une demi-solution.
Quatrième étape : chercher le « mur suivant »
- Trafic inter-socket (NUMA distant), tempêtes de cohérence de cache, contention sur les locks, goulots PCIe.
- Si l’HBM aide un peu mais pas assez, vous avez peut-être des limiteurs mixtes.
Tâches pratiques : commandes, sorties et la décision que vous prenez
Ce sont des tâches pratiques en on-call. Chacune inclut une commande, une sortie réaliste, ce que ça signifie et la décision à prendre.
Hypothèse : hôte Linux avec root ou sudo. Les outils peuvent nécessiter des paquets, mais les commandes elles-mêmes sont standards et exécutables si installés.
Task 1: Confirm NUMA topology (do we even have distinct memory nodes?)
cr0x@server:~$ numactl --hardware
available: 4 nodes (0-3)
node 0 cpus: 0 1 2 3 4 5 6 7
node 0 size: 256000 MB
node 0 free: 194321 MB
node 1 cpus: 8 9 10 11 12 13 14 15
node 1 size: 256000 MB
node 1 free: 200114 MB
node 2 cpus: 16 17 18 19 20 21 22 23
node 2 size: 64000 MB
node 2 free: 61222 MB
node 3 cpus: 24 25 26 27 28 29 30 31
node 3 size: 64000 MB
node 3 free: 63001 MB
node distances:
node 0 1 2 3
0: 10 12 20 20
1: 12 10 20 20
2: 20 20 10 12
3: 20 20 12 10
Ce que cela signifie : Deux nœuds larges et deux nœuds plus petits suggèrent un niveau rapide/petit (souvent HBM) et un grand niveau (DDR), selon la plateforme.
Décision : Identifiez quels nœuds sont HBM vs DDR avant d’ajuster. Ne vous liez pas aveuglément à « node 0 » par habitude.
Task 2: Map NUMA nodes to memory types (DAX/pmem vs DRAM vs HBM-like)
cr0x@server:~$ for n in /sys/devices/system/node/node*; do echo "$n"; cat $n/meminfo | head -n 5; done
/sys/devices/system/node/node0
Node 0 MemTotal: 262144000 kB
Node 0 MemFree: 198930432 kB
Node 0 MemUsed: 63213568 kB
Node 0 Active: 21011200 kB
Node 0 Inactive: 18400320 kB
/sys/devices/system/node/node1
Node 1 MemTotal: 262144000 kB
Node 1 MemFree: 205019136 kB
Node 1 MemUsed: 57124864 kB
Node 1 Active: 20122304 kB
Node 1 Inactive: 17633280 kB
/sys/devices/system/node/node2
Node 2 MemTotal: 65536000 kB
Node 2 MemFree: 62691328 kB
Node 2 MemUsed: 2844672 kB
Node 2 Active: 412160 kB
Node 2 Inactive: 671744 kB
/sys/devices/system/node/node3
Node 3 MemTotal: 65536000 kB
Node 3 MemFree: 64513024 kB
Node 3 MemUsed: 1022976 kB
Node 3 Active: 210944 kB
Node 3 Inactive: 312320 kB
Ce que cela signifie : Les nœuds plus petits représentent probablement le niveau « rapide » ; vérifiez via la documentation de la plateforme, le firmware ou des tests de performance.
Décision : Considérez node2/node3 comme candidats pour l’HBM. Planifiez de lier des charges de test à eux et de mesurer.
Task 3: Check current memory policy of a running process
cr0x@server:~$ sudo cat /proc/12345/numa_maps | head -n 5
00400000 default file=/usr/bin/myservice mapped=4 N0=4
00a00000 default heap anon=512 N0=320 N2=192
7f2c84000000 default anon=2048 N1=2048
7f2c8c000000 interleave anon=4096 N2=2048 N3=2048
Ce que cela signifie : Le heap est réparti entre les nœuds, incluant N2/N3. Certaines mappings sont interleaved.
Décision : Si l’allocation chaude n’est pas sur le niveau prévu, ajustez la politique de lancement ou l’allocateur. Ne vous contentez pas d’« optimiser » en n’épinglant que les CPU.
Task 4: Confirm whether automatic NUMA balancing is migrating pages
cr0x@server:~$ cat /proc/sys/kernel/numa_balancing
1
Ce que cela signifie : Le kernel peut migrer des pages selon les schémas d’accès observés, parfois hors de l’HBM selon les heuristiques.
Décision : Pour des benchmarks contrôlés, désactivez-le temporairement ; en production, décidez par service. Si l’HBM est une cible, vous pourriez préférer des politiques explicites.
Task 5: Launch a workload explicitly bound to HBM-like nodes (memory + CPU)
cr0x@server:~$ numactl --cpunodebind=2 --membind=2 -- bash -lc 'python3 -c "a=bytearray(8*1024*1024*1024); print(len(a))"'
8589934592
Ce que cela signifie : L’allocation a réussi sur le node 2. Si elle échoue avec ENOMEM, la capacité HBM est plus petite que prévu.
Décision : Si ça rentre, mesurez la performance. Si ce n’est pas le cas, choisissez l’interleave ou un design tiered (chaud en HBM, froid en DDR).
Task 6: Measure memory bandwidth quickly (stream-like sanity test)
cr0x@server:~$ sudo perf stat -e cycles,instructions,cache-misses,LLC-load-misses -a -- sleep 10
Performance counter stats for 'system wide':
42,118,443,002 cycles
55,220,114,887 instructions # 1.31 insn per cycle
1,220,443,119 cache-misses
410,221,009 LLC-load-misses
10.003857036 seconds time elapsed
Ce que cela signifie : IPC ~1.31 avec des LLC misses substantielles suggère une pression mémoire. Pas définitif, mais c’est un signal.
Décision : Si vous voyez un IPC faible avec de nombreux LLC misses durant la période lente, concentrez-vous sur le placement/bande passante mémoire, pas sur l’augmentation CPU.
Task 7: Spot remote NUMA access (the silent latency tax)
cr0x@server:~$ numastat -p 12345
Per-node process memory usage (in MBs) for PID 12345 (myservice)
Node 0 1200.45
Node 1 1188.20
Node 2 256.10
Node 3 12.05
Total 2656.80
Ce que cela signifie : La plupart de la mémoire est sur Node0/Node1. Si les threads tournent sur les CPU de Node2, vous payez l’accès distant.
Décision : Alignez l’affinité CPU et mémoire. Déplacez soit les threads pour correspondre à la mémoire, soit migrez la mémoire pour correspondre aux threads.
Task 8: Check CPU affinity for the process (are we pinning ourselves into a corner?)
cr0x@server:~$ taskset -pc 12345
pid 12345's current affinity list: 16-23
Ce que cela signifie : Le processus est épinglé sur les CPU 16–23 (probablement node2). Si la mémoire est sur node0/1, le trafic distant est garanti.
Décision : Ajustez l’affinité vers des nœuds DDR locaux, ou utilisez --membind/--preferred vers node2 si c’est votre niveau HBM et que la capacité suffit.
Task 9: Check memory bandwidth/uncore counters via pcm (if installed)
cr0x@server:~$ sudo pcm-memory 1 -csv=/tmp/pcm.csv
PCM Memory Bandwidth Monitoring Utility
Time elapsed: 1.00 seconds
System Read Throughput(MB/s): 182400.12
System Write Throughput(MB/s): 62211.55
Ce que cela signifie : La bande passante est extrêmement élevée ; vous pouvez saturer les canaux DDR ou le fabric. L’HBM devrait réduire la pression si utilisée.
Décision : Si la bande passante est proche des limites de la plateforme, priorisez le maintien des données chaudes en HBM et réduisez le bavardage inter-socket.
Task 10: Detect page faults and major faults (are we paging or thrashing the tiers?)
cr0x@server:~$ pidstat -r -p 12345 1 5
Linux 6.5.0 (server) 01/12/2026 _x86_64_ (32 CPU)
12:01:11 UID PID minflt/s majflt/s VSZ RSS %MEM Command
12:01:12 1000 12345 5020.00 0.00 28934144 2638820 8.12 myservice
12:01:13 1000 12345 4870.00 0.00 28934144 2638900 8.12 myservice
Ce que cela signifie : Les minor faults élevés sont normaux pendant l’allocation/first-touch ; les major faults indiqueraient du swapping.
Décision : Si les major faults augmentent en steady state, vous avez des problèmes de capacité ; l’HBM ne vous aidera pas forcément et peut même aggraver la situation.
Task 11: Verify transparent hugepages status (THP can help or hurt)
cr0x@server:~$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
Ce que cela signifie : THP est toujours activé. Cela peut améliorer le comportement du TLB pour de grands scans, mais aussi provoquer des pics de latence dus à la compaction.
Décision : Pour des services sensibles à la latence, envisagez madvise et des stratégies de hugepages explicites ; pour des batchs gourmands en bande passante, always peut convenir.
Task 12: Check page migration activity (are pages bouncing between tiers?)
cr0x@server:~$ grep -E 'pgmigrate|numa' /proc/vmstat | head
numa_pte_updates 18422011
numa_huge_pte_updates 11201
numa_hint_faults 920110
numa_hint_faults_local 610022
numa_pages_migrated 188440
pgmigrate_success 188102
pgmigrate_fail 338
Ce que cela signifie : Des pages sont en migration. Un peu est normal ; beaucoup peut indiquer que le kernel lutte contre votre placement ou que la charge est instable.
Décision : Si les migrations corrèlent avec des pics p99, réduisez le balancing automatique ou rendez le placement explicite. La migration n’est pas gratuite.
Task 13: Validate per-node free memory before forcing membind (avoid OOM surprises)
cr0x@server:~$ grep -H "MemFree" /sys/devices/system/node/node*/meminfo
/sys/devices/system/node/node0/meminfo:Node 0 MemFree: 198930432 kB
/sys/devices/system/node/node1/meminfo:Node 1 MemFree: 205019136 kB
/sys/devices/system/node/node2/meminfo:Node 2 MemFree: 62691328 kB
/sys/devices/system/node/node3/meminfo:Node 3 MemFree: 64513024 kB
Ce que cela signifie : Les nœuds rapides ont bien moins de mémoire libre. Un --membind strict peut échouer sous charge alors que la machine a beaucoup de DDR libre.
Décision : Utilisez --preferred ou l’interleave pour la résilience sauf si vous êtes absolument sûr que les allocations tiennent dans la marge HBM.
Task 14: Compare performance quickly: preferred vs interleave
cr0x@server:~$ /usr/bin/time -f "elapsed=%e cpu=%P" numactl --preferred=2 -- bash -lc 'dd if=/dev/zero of=/dev/null bs=1M count=4096 status=none'
elapsed=0.34 cpu=99%
cr0x@server:~$ /usr/bin/time -f "elapsed=%e cpu=%P" numactl --interleave=all -- bash -lc 'dd if=/dev/zero of=/dev/null bs=1M count=4096 status=none'
elapsed=0.52 cpu=99%
Ce que cela signifie : L’allocation préférée vers node2 était plus rapide pour ce pattern streaming, ce qui suggère que node2 a une mémoire à plus haute bande passante.
Décision : Utilisez la préférence HBM pour les allocations gourmandes en bande passante, mais validez la stabilité sous pression mémoire réelle.
Trois mini-histoires d’entreprise tirées du terrain
Mini-histoire 1 : L’incident causé par une mauvaise hypothèse
Une entreprise de taille moyenne a déplacé un service de ranking sensible à la latence vers de nouveaux hôtes CPU annoncés « HBM-enabled ».
Le plan de migration était simple : mêmes limites de conteneur, même politique d’épinglage CPU, même template de déploiement. Matériel plus rapide, même logiciel. Que pourrait-il arriver ?
Les premières heures semblaient correctes. Puis le p99 a commencé à grimper lors des pics de trafic, alors que l’utilisation CPU restait modeste.
L’équipe a scalé horizontalement. Ça a aidé un peu. Ils ont scalé encore. Ça aidait moins. Entre-temps, l’utilisation mémoire semblait « dans les limites », et personne n’a vu de swap.
La mauvaise hypothèse : ils croyaient que l’HBM était un cache transparent. Sur cette plateforme, il était exposé comme des nœuds NUMA séparés,
et leur déploiement épinglait les CPU au nœud « adjacent HBM » tandis que les allocations mémoire par défaut allaient sur le grand nœud DDR à cause du comportement first-touch dans un thread d’échauffement.
Les pages chaudes étaient loin, chaque requête payait l’accès distant, et l’interconnect était saturé.
La correction a été presque ennuyeuse : aligner le placement CPU et mémoire, modifier l’échauffement pour qu’il s’exécute sur le même nœud que les threads de service, et utiliser --preferred plutôt qu’un membind strict.
La performance s’est stabilisée immédiatement. La grande leçon n’était pas « l’HBM est compliqué ». C’était « les hypothèses sur la topologie sont des bugs en production ».
Mini-histoire 2 : L’optimisation qui a échoué
Une autre organisation a lancé un job analytics en mémoire lourd. Ils ont obtenu des nœuds compatibles HBM et voulaient la bande passante maximale, donc ils ont lancé le job avec un binding strict :
CPU épinglé au nœud HBM et --membind pour forcer toutes les allocations dans l’HBM.
En benchmark unique, c’était magnifique. Puis ils ont lancé deux jobs par hôte et tout s’est écroulé.
Certaines exécutions échouaient avec out-of-memory bien que l’hôte ait beaucoup de DDR libre. D’autres « fonctionnaient » mais étaient plus lentes que sur les anciens hôtes DDR-only.
Ce qui s’est passé : la capacité HBM était plus petite que leur working set, et le membind strict a transformé « niveau rapide plein » en « échec d’allocation ».
Quand ça ne plantait pas, le kernel et l’allocateur se battaient contre la fragmentation ; les grosses allocations étaient fragmentées, la migration de pages commencait, et le système passait du temps à juste déplacer des pages.
La correction a été de traiter l’HBM comme un niveau « chaud », pas comme toute la maison.
Ils ont gardé l’ensemble de travail le plus chaud en HBM en utilisant une allocation préférée et ont ajusté la concurrence pour que l’ensemble chaud agrégé tienne.
Le job est devenu légèrement plus lent en benchmark simple mais beaucoup plus rapide et fiable en débit production par nœud.
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une équipe plateforme avait l’habitude, qu’ingénieurs aiment se moquer, de soumettre chaque nouvelle classe de matériel à une batterie d’acceptation « ennuyeuse ».
Pas un deck de benchmarks fancy. Une checklist répétable : vérifier la topologie NUMA, vérifier la sanity de bande passante par nœud, vérifier le comportement de migration de pages, vérifier le reporting ECC,
et enregistrer des baselines sous une version OS et firmware fixe.
Quand leur première vague de serveurs HBM-enabled est arrivée, la suite a immédiatement signalé quelque chose d’étrange : la bande passante d’un nœud NUMA était bien en dessous des attentes.
L’hôte ne semblait pas « cassé ». Pas d’erreurs kernel. Pas d’alarmes thermiques évidentes. Il sous-performait simplement.
Ils ont creusé et trouvé un problème de configuration firmware qui désactivait effectivement une partie du mode mémoire prévu.
Rien de dramatique—juste un réglage incohérent entre racks. Mais sans la suite d’acceptation, le problème serait apparu comme une plainte vague et de longue durée : « cette flotte est plus lente ».
Ils ont corrigé la configuration avant le déploiement général. Pas d’héroïsme, pas d’appel incident, pas de postmortem gênant sur pourquoi personne n’a remarqué pendant huit semaines.
La pratique qui les a sauvés n’était pas de la génie ; c’était de la répétition.
Erreurs courantes : symptômes → cause racine → correction
1) Symptom: CPU utilization is low, but throughput doesn’t increase with more threads
Cause racine : Charge limitée par la bande passante ; les cœurs sont stallés sur la mémoire ou le trafic de cohérence.
Correction : Mesurez les compteurs de bande passante mémoire ; déplacez les données chaudes vers l’HBM ; réduisez le partage inter-socket ; préférez les grandes pages quand approprié.
2) Symptom: HBM node shows lots of free memory, but performance doesn’t improve
Cause racine : Les pages sont allouées sur le DDR à cause du first-touch ou du comportement de l’allocateur ; l’HBM est inutilisé.
Correction : Appliquez numactl --preferred/--membind au lancement ; assurez-vous que l’échauffement s’exécute sur le nœud prévu ; validez via /proc/<pid>/numa_maps.
3) Symptom: Sudden allocation failures (OOM) despite plenty of RAM free
Cause racine : Binding strict sur un petit niveau HBM ; le nœud local est à court alors que le DDR a de la marge.
Correction : Utilisez une allocation préférée plutôt qu’un membind strict ; limitez la concurrence ; redesign pour ne garder que l’ensemble chaud en HBM.
4) Symptom: p99 spikes appear after enabling NUMA balancing
Cause racine : Coût de migration de pages, surtout avec de gros heaps ; le kernel déplace des pages entre niveaux sous charge.
Correction : Ajustez ou désactivez le NUMA balancing par service ; rendez le placement explicite ; alignez affinité CPU et politique mémoire pour réduire les migrations.
5) Symptom: Great single-job benchmark, terrible multi-tenant behavior
Cause racine : L’HBM est un niveau partagé et rare ; plusieurs jobs se battent et s’évincet les pages chaudes mutuellement.
Correction : Partitionnez l’HBM par cgroup/politique NUMA ; planifiez moins de jobs gourmands en bande passante par hôte ; séparez les voisins bruyants.
6) Symptom: Performance regresses after switching to huge pages
Cause racine : Coûts de compaction/migration accrus ; fragmentation de l’allocateur ; mauvaise stratégie de hugepage pour le pattern d’accès.
Correction : Utilisez madvise pour THP ; épinglez des huge pages seulement pour les régions qui en bénéficient ; validez avec des histogrammes de latence, pas des moyennes.
7) Symptom: Remote memory access grows over time even though affinity was set
Cause racine : Les threads migrent, de nouveaux threads sont créés sans épinglage, ou la politique mémoire est héritée de façon incohérente lors d’exec/fork.
Correction : Faites respecter l’affinité au niveau du gestionnaire de service ; auditez la création de threads ; revérifiez après les déploiements ; validez avec numastat -p.
Listes de vérification / plan étape par étape
Plan étape par étape : évaluer des hôtes CPU compatibles HBM pour une charge
- Classifiez la charge : stream gourmand en bande passante ? accès aléatoire sensible à la latence ? mixte ? Si vous ne pouvez pas répondre, vous n’êtes pas prêt à acheter du matériel.
- Vérifiez l’exposition matérielle : confirmez si l’HBM est en mode cache ou en nœud(s) NUMA plats. Enregistrez-le.
- Faites une baseline sur placement DDR-only : lancez la charge avec la mémoire contrainte aux nœuds DDR pour obtenir une référence équitable.
- Testez le placement HBM préféré : utilisez
--preferredavant d’utiliser--membind. - Testez le comportement en échec : lancez deux instances par hôte, puis trois. Surveillez ENOMEM et les explosions de migration de pages.
- Vérifiez l’accès distant : confirmez que l’affinité CPU et le placement mémoire restent alignés en steady state.
- Surveillez la latence tail : acceptez que le débit moyen n’est pas votre SLA. Si la migration cause des pics p99, considérez cela comme une régression.
- Opérationnalisez : intégrez les vérifications de topologie et la validation de placement dans les pipelines de provisioning et de déploiement.
- Décidez de la politique de scheduling : les jobs gourmands en bande passante doivent être limités par hôte ; traitez l’HBM comme une ressource quota.
- Déployez le tableau de bord : usage mémoire par nœud, migrations, indicateurs d’accès distant et compteurs de bande passante doivent être visibles avant le premier incident.
Checklist Do et Don’t pour la production
- Do : considérez la capacité HBM comme une contrainte de production stricte. Suivez-la comme l’espace disque.
- Do : vérifiez le placement avec
/proc/<pid>/numa_mapsetnumastataprès le déploiement. - Do : commencez par
--preferredpour éviter des échecs d’allocation fragiles. - Don’t : supposez que l’HBM est « toujours plus rapide ». Certaines charges sont liées à la latence, pas à la bande passante.
- Don’t : épinglez les CPU sans épingler la mémoire. C’est comme fabriquer de l’accès distant volontairement.
- Don’t : benchmarkez en mono-tenant puis déployez en multi-tenant sans retester. L’HBM change la dynamique de contention.
FAQ
1) Is HBM on CPUs the same thing as “unified memory” on GPUs?
Non. Les GPU parlent de mémoire unifiée comme modèle de programmation entre espaces adresse CPU/GPU. L’HBM sur CPU est un niveau mémoire physique avec une bande passante/capacité différente,
généralement géré par des politiques OS ou des allocateurs.
2) Will HBM replace DDR in servers?
Pas de manière générale. L’HBM est trop cher par GB et trop petit par socket pour les flottes générales. Attendez-vous à des systèmes hybrides : HBM on-package plus DDR pour la capacité.
3) Is HBM always lower latency than DDR?
Pas systématiquement. L’avantage affiché de l’HBM est la bande passante. La latence effective dépend de la plateforme, de la contention et de l’accès local ou distant.
4) If I have HBM, should I disable CPU caches or change cache settings?
Non. Les caches restent importants. L’HBM ne remplace pas L1/L2/L3 ; elle réduit la pression sur le sous-système mémoire pour les données qui manquent les caches.
Concentrez-vous sur le placement et les patterns d’accès, pas sur la superstition des caches.
5) What’s the simplest safe policy to start with?
Commencez par numactl --preferred=<HBM node> plutôt que par un --membind strict.
Le mode preferred utilise l’HBM quand disponible mais retombe sur le DDR au lieu d’échouer les allocations.
6) How does this interact with containers and Kubernetes?
L’épinglage CPU est courant ; l’épinglage mémoire l’est moins. Si vous placez des pods sur des « nœuds HBM » sans appliquer la politique mémoire, vous pouvez obtenir des régressions d’accès distant.
Traitez l’HBM comme une ressource schedulable ou utilisez des wrappers au niveau nœud qui définissent la politique mémoire au lancement.
7) Does CXL make HBM irrelevant?
Non. CXL est excellent pour étendre et mettre en pool la mémoire avec une latence plus élevée. L’HBM sert pour la bande passante proche du compute.
Dans un futur en niveaux, vous pouvez avoir HBM (rapide), DDR (gros) et CXL (encore plus gros) simultanément.
8) What’s the biggest operational risk with HBM-equipped CPU hosts?
Le mauvais placement : des pages chaudes qui atterrissent dans le niveau lent pendant que le niveau rapide reste inactif, ou des bindings stricts causant des échecs d’allocation.
Le symptôme est une « lenteur mystérieuse » sans saturation évidente. La correction est la conscience de la topologie et la vérification des politiques.
9) What should I put on dashboards for an HBM fleet?
Usage mémoire par nœud NUMA, indicateurs d’accès distant, compteurs de bande passante mémoire (uncore), migrations de pages et latence p99.
L’utilisation CPU seule est pratiquement décorative.
Prochaines étapes pratiques
Si vous décidez si l’HBM sur CPU a sa place dans votre flotte, ne commencez pas par les slides du vendeur. Commencez par vos goulots.
Prouvez que vous êtes limité par la bande passante, puis prouvez que vous pouvez garder les données chaudes dans le niveau rapide sans politiques fragiles.
- Cette semaine : exécutez le « Guide de diagnostic rapide » sur une charge lente et identifiez si le limiteur est la bande passante, la latence ou le NUMA distant.
- Ce mois-ci : construisez une suite d’acceptation répétable pour les nouvelles classes de matériel : topologie, sanity de bande passante, comportement de migration et baseline p99 sous charge contrôlée.
- Avant d’acheter du matériel : modélisez l’HBM comme une ressource quota rare et décidez comment vous la schedulerez, l’observerez et l’empêcherez de devenir une tragédie partagée.
La mémoire qui entre dans le package n’est pas un scénario de science-fiction lointain. C’est l’industrie qui admet que la bande passante est un budget que vous pouvez brûler.
Traitez-le comme tel, et les CPU compatibles HBM sont un outil tranchant. Traitez-le comme de la « RAM plus rapide », et vous le rencontrerez pendant un incident.