Vous achetez une station de travail « 16 cœurs », lancez un build, et le graphe de latence ressemble à un sismographe en pleine crise existentielle mineure.
Ou vous provisionnez un hôte EPYC flambant neuf, puis vous regardez un microservice voler tandis qu’un autre rampe — même code, même charge, même jour.
Voilà l’ère des chiplets en production : des cœurs moins chers, plus nombreux, et une topologie qui punira absolument les suppositions paresseuses.
La stratégie chiplet d’AMD n’a pas seulement « aidé les performances ». Elle a ressuscité Ryzen comme ligne de produits en changeant les mathématiques de fabrication — et elle a changé
la façon dont les opérateurs doivent diagnostiquer les goulets d’étranglement, placer la mémoire et épingler le travail.
Chiplets en une phrase (et pourquoi c’était important)
Un CPU chiplet est un processeur construit à partir de plusieurs dies plus petits — typiquement des dies de cœurs CPU plus un die d’E/S — connectés par une interconnexion à haute vitesse.
Si vous êtes SRE, traduisez cela par : le calcul est modulaire, l’E/S est centralisée, et l’accès mémoire n’est plus « uniforme » même lorsque votre ordonnanceur fait comme si.
Si vous êtes ingénieur stockage, traduisez-le par : PCIe et contrôleurs mémoire vivent sur un die différent des cœurs qui effectuent vos checksums, codage d’effacement,
compression et mise en réseau.
AMD a rendu cela grand public. Et AMD l’a fait précisément au moment où les dies monolithiques à fort nombre de cœurs devenaient dangereusement coûteux à fabriquer de manière fiable.
Les chiplets ont été l’astuce qui a permis à AMD d’expédier beaucoup de cœurs avec des fréquences compétitives et des marges raisonnables, tout en itérant rapidement entre les générations.
Contexte historique rapide : les faits concrets qui ont préparé le terrain
Quelques faits importent parce qu’ils expliquent pourquoi les chiplets n’étaient pas un choix de design mignon — ils étaient une issue de secours. Gardez-les à portée de main.
- Les premiers CPU desktop Ryzen basés sur Zen d’AMD ont été lancés en 2017, mettant fin à une longue période où le débat « AMD vs Intel » n’était pas sérieux sur de nombreux segments.
- Zen 2 (2019) a été le grand pivot chiplet pour le grand public : les cœurs CPU ont été déplacés vers plusieurs dies plus petits, associés à un die d’E/S séparé sur un nœud de processus différent.
- Le die I/O dans Zen 2 était généralement sur un nœud mature (plus ancien, moins cher, meilleur rendement), tandis que les chiplets de cœurs CPU étaient sur un nœud de pointe.
- EPYC « Rome » (Zen 2) a monté en échelle avec de nombreux chiplets dans les serveurs, prouvant le modèle à fort nombre de cœurs avant que les desktops n’en absorbent pleinement les implications.
- Infinity Fabric est devenu l’« épine dorsale » qui a rendu le calcul modulaire faisable sans transformer chaque miss de cache en catastrophe.
- L’économie des rendements est devenue brutale aux nœuds avancés : plus le die est grand, plus un défaut a de chances de ruiner la pièce entière. Les dies plus petits améliorent le nombre de pièces utilisables par wafer.
- Les chiplets ont permis un binning produit agressif : AMD pouvait mixer les chiplets de cœurs et segmenter les SKU sans concevoir un nouveau die monolithique à chaque fois.
- Les ordonnanceurs Windows et Linux ont dû rattraper leur retard : la conscience topologique compte davantage quand les cœurs sont séparés en dies et que les contrôleurs mémoire sont ailleurs.
L’histoire n’est pas « AMD a inventé les chiplets. » L’histoire est qu’AMD les a opérationnalisés à grande échelle pour les pièces grand public et serveur d’une manière qui a changé la pente prix/performances.
Comment fonctionnent réellement les chiplets d’AMD : CCD, IOD et le fabric entre eux
Les éléments : CCD et IOD
Dans les designs chiplet d’AMD, vous avez généralement :
- CCD (Core Complex Die) : le tile de calcul. C’est là que vivent les cœurs CPU et leurs caches.
- IOD (I/O Die) : le tile qui héberge les contrôleurs mémoire, les contrôleurs PCIe, et souvent d’autres infrastructures « peu cool » mais essentielles.
- Interconnexion : Infinity Fabric relie ces dies.
Opérationnellement, cela signifie que le cœur CPU exécutant votre processus peut être à un saut de die du contrôleur mémoire traitant son trafic DRAM et à un saut de die du root complex PCIe transportant les interruptions NVMe. Ce saut est rapide. Il n’est pas gratuit.
La topologie : « NUMA, mais en plus subtil »
NUMA est plus ancien que la plupart des tableaux de bord que nous regardons. Mais les chiplets l’ont rendu pertinent pour des gens qui avaient l’habitude de l’ignorer.
Même au sein d’un seul socket, la latence vers la mémoire peut varier en fonction du CCD sur lequel votre cœur se trouve et du contrôleur mémoire (sur l’IOD) qui sert la requête.
Voici la définition pratique : si une charge est cache-friendly, les chiplets sont majoritairement bénéfiques. Si elle est sensible à la latence mémoire avec beaucoup d’accès aléatoire,
les chiplets peuvent se transformer en taxe topologique à moins de planifier et allouer soigneusement.
Infinity Fabric : ce qu’il donne, ce qu’il facture
Infinity Fabric est l’interconnexion qui assemble les dies. Ce n’est pas « juste un bus. » C’est un écosystème : horloge, cohérence,
et la façon dont les dies de cœurs parlent au die I/O et, dans les systèmes multisocket, potentiellement à un autre socket.
Concrètement :
- Meilleur cas : le fabric est assez rapide pour que la modularité se fasse oublier, et vous obtenez beaucoup de cœurs à bon prix.
- Pire cas : vous planifiez des threads à travers des dies, faites rebondir des lignes de cache, et transformez votre latence p99 en un trait de personnalité.
Une citation pour vous garder honnête quand vous êtes tenté de minimiser la topologie :
La latence est une taxe que vous payez sur chaque requête ; le débit est un dividende que vous pouvez ou non collecter.
— Brendan Gregg (idée paraphrasée)
Deux blagues au total, utilisées avec responsabilité
Blague 1 : Les chiplets sont super parce que maintenant vous pouvez avoir huit petits CPU qui se disputent la cohérence du cache au lieu d’un gros CPU qui le fait tranquillement.
Pourquoi cela a ressuscité Ryzen : rendements, binning, cadence et segmentation produit
Économie de fabrication : dies plus petits, meilleurs rendements
Soyons francs : les chiplets permettent à AMD de vendre plus de silicium utilisable par wafer. Les défauts arrivent. Ils sont normaux. Ce qui importe, c’est combien de produit vous pouvez sauver.
Avec un gros die monolithique, un défaut peut détruire beaucoup de surface. Avec plusieurs dies plus petits, un défaut détruit un seul chiplet.
Cela change tout : coût par cœur utilisable, jusqu’où vous pouvez pousser les nombres de cœurs, et combien de SKU vous pouvez expédier de manière rentable.
Cela signifie aussi qu’AMD peut utiliser les nœuds de pointe pour les cœurs tout en gardant l’IOD sur un nœud mature, moins cher et souvent plus simple électriquement pour les interfaces analogiques.
Flexibilité de binning : mixer les bonnes pièces dans de bons produits
Les chiplets débloquent un binning pratique. Si un CCD a un cœur légèrement moins performant, vous pouvez downgrader ce chiplet dans un SKU inférieur. Un autre CCD avec de meilleures caractéristiques
peut aller dans un SKU à fréquence plus élevée. L’IOD reste de la même famille. Cette modularité maintient la gamme de produits pleine sans exiger des rendements héroïques.
C’est aussi ainsi que vous obtenez des parties milieu de gamme « étrangement bonnes » qui overclockent comme si elles voulaient prouver quelque chose : elles sont souvent faites de chiplets excellents qui
ne rentraient pas dans un SKU supérieur pour des raisons autres que les performances (inventaire, demande, segmentation).
Itération plus rapide : mettre à jour l’I/O séparément des cœurs (ou inversement)
Avec les chiplets, AMD peut faire évoluer l’architecture des cœurs et le nœud de procédé sans refaire tout le sous-système d’I/O à la même cadence.
Cela réduit le risque. Cela réduit aussi le time-to-market. L’IOD est complexe et rempli d’interfaces qui sont douloureuses au cutting edge.
Pour les opérateurs, l’effet en aval est subtil : vous verrez des générations où le calcul brut bondit, mais la latence mémoire ou le comportement d’E/S changent différemment.
N’assumez pas que « nouveau CPU » signifie « même topologie avec plus de GHz ».
Segmenter desktop vs serveur sans tout réinventer
AMD peut scaler les mêmes blocs de base à travers les familles Ryzen et EPYC, ajustant les comptes et les fonctionnalités d’I/O pour correspondre aux marchés.
Ce n’est pas seulement une efficacité commerciale — c’est pourquoi Ryzen est revenu avec des performances crédibles et pourquoi EPYC est devenu une option sérieuse pour les centres de données.
Réalité des opérations : où les chiplets aident, et où ils mordent
Où les chiplets sont clairement gagnants
- Charges parallèles : fermes de build, rendu, compression, chiffrement, analytics, consolidation de VM — tout ce qui scale avec les cœurs et tolère une certaine variance de localité.
- Échelle rentable : plus de cœurs par dollar bat souvent un p99 légèrement inférieur, à condition d’être honnête sur les besoins de latence de queue.
- Disponibilité et diversité de SKU : le marché finit par avoir plus de CPU « étrangement spécifiques » qui conviennent à des rôles de flotte précis.
Où les chiplets vous punissent
Le mode d’échec n’est généralement pas « lent ». C’est « incohérent ». Un run est ok. Le run suivant est 30 % pire. Puis vous redémarrez et ça s’améliore,
ce qui convainc tout le monde que c’était « transitoire ». Ce n’était pas le cas.
- Ordonnancement aveugle au NUMA : threads et allocations mémoire dérivent à travers les dies.
- Tempêtes d’interruptions sur de mauvais cœurs : les interruptions NIC/NVMe frappent un CCD éloigné du travail.
- Contention de verrous inter-die : des structures de données partagées font rebondir les lignes de cache sur le fabric.
- Sensibilité à la latence mémoire : magasins clé-valeur, workloads de trading, certaines bases de données, et tout ce qui implique du pointer-chasing.
Blague 2 : Si vos performances « s’améliorent après un reboot », félicitations — vous avez inventé la roulette topologique.
Que faire à ce sujet (haut niveau)
Traitez la topologie comme une ressource de première classe. Cela signifie :
- Mesurer la latence et la bande passante mémoire, pas seulement l’utilisation CPU.
- Épingler les charges critiques et leur mémoire sur le même nœud NUMA quand c’est possible.
- Être délibéré sur les réglages BIOS qui modifient les horloges du fabric, les états d’alimentation et l’interleaving mémoire.
- Surveiller la distribution des interruptions et l’affinité des queues sur les NIC et NVMe à haut débit.
Mode d’emploi de diagnostic rapide : trouvez le goulet avant la fin de la réunion
Quand un hôte Ryzen/EPYC chiplet se sent « bizarre », vous n’avez pas le temps de philosopher. Vous avez besoin d’un ordre de triage rapide qui réduit l’espace.
Premier : confirmez la topologie et l’exposition NUMA
- Combien de nœuds NUMA l’OS voit-il ? Correspondent-ils aux attentes ?
- La mémoire est-elle peuplée uniformément sur les canaux ?
- Les cœurs sont-ils répartis sur les CCD d’une manière que l’ordonnanceur comprend ?
Deuxième : décidez si le goulet est CPU, mémoire ou E/S
- Limité par le CPU : IPC élevé, forte utilisation des cœurs, p99 stable.
- Limité par la mémoire : IPC faible, cycles en attente élevés, nombreux misses LLC, trafic NUMA inégal.
- Limité par l’E/S : files qui s’allongent, iowait élevé, interruptions sur un petit sous-ensemble de CPU, throttling PCIe, pics de latence NVMe.
Troisième : vérifiez les « accidents topologiques »
- Workloads migrent entre nœuds NUMA (cpuset/cgroup mal configuré ou comportement de l’ordonnanceur).
- Interruptions NIC/NVMe mal épinglées.
- Allocations mémoire éloignées des threads qui les utilisent (NUMA balancing qui vous combat).
Quatrième : validez les réglages firmware et le comportement d’alimentation
- Couplage des horloges du fabric, vitesse mémoire et états d’alimentation (C-states, CPPC, P-states).
- Décisions SMT activé/désactivé pour la latence tail.
- Profils de performance déterministes si votre fournisseur les propose.
Cinquième : ne touchez l’application qu’ensuite
Si la topologie est fausse, les réglages applicatifs ne sont que du théâtre de performance. Corrigez le placement d’abord.
Tâches pratiques avec commandes : prouver la topologie, mesurer, décider
Ce sont des tâches que j’exécute réellement quand la topologie chiplet est suspectée. Chacune inclut : une commande, ce que la sortie signifie, et la décision que vous prenez.
Hypothèse : hôte Linux. Si vous utilisez autre chose, votre journée est déjà assez compliquée.
Task 1: Identify the CPU model and stepping
cr0x@server:~$ lscpu | egrep 'Model name|Socket|Thread|Core|NUMA|Vendor|CPU\(s\)'
CPU(s): 64
Vendor ID: AuthenticAMD
Model name: AMD EPYC 7xx2 32-Core Processor
Thread(s) per core: 2
Core(s) per socket: 32
Socket(s): 1
NUMA node(s): 4
NUMA node0 CPU(s): 0-15
NUMA node1 CPU(s): 16-31
NUMA node2 CPU(s): 32-47
NUMA node3 CPU(s): 48-63
Signification : Un socket, 4 nœuds NUMA exposés. C’est un signal topologique : la localité mémoire compte même « au sein d’un seul CPU ».
Décision : Si la charge est sensible à la latence, planifiez l’épinglage NUMA et la liaison mémoire ; sinon acceptez-le et concentrez-vous sur le débit.
Task 2: Validate NUMA memory availability per node
cr0x@server:~$ numactl --hardware
available: 4 nodes (0-3)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 64512 MB
node 0 free: 60210 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 64512 MB
node 1 free: 61102 MB
node 2 cpus: 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
node 2 size: 64512 MB
node 2 free: 60001 MB
node 3 cpus: 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
node 3 size: 64512 MB
node 3 free: 61234 MB
node distances:
node 0 1 2 3
0: 10 12 12 12
1: 12 10 12 12
2: 12 12 10 12
3: 12 12 12 10
Signification : La mémoire est provisionnée de façon équilibrée ; la matrice de distances montre le coût local vs distant.
Décision : Si un nœud a beaucoup moins de mémoire (ou est absent), corrigez la population de DIMM ou l’interleaving BIOS avant de blâmer l’application.
Task 3: Verify memory speed and channel population signals
cr0x@server:~$ sudo dmidecode -t memory | egrep 'Locator:|Speed:|Configured Memory Speed:|Size:'
Locator: DIMM_A1
Size: 32 GB
Speed: 3200 MT/s
Configured Memory Speed: 3200 MT/s
Locator: DIMM_B1
Size: 32 GB
Speed: 3200 MT/s
Configured Memory Speed: 3200 MT/s
Locator: DIMM_C1
Size: 32 GB
Speed: 3200 MT/s
Configured Memory Speed: 3200 MT/s
Locator: DIMM_D1
Size: 32 GB
Speed: 3200 MT/s
Configured Memory Speed: 3200 MT/s
Signification : La vitesse configurée correspond à la vitesse nominale. Si vous voyez 2133/2400 sur une plateforme qui devrait tourner à 3200, vous payez une pénalité silencieuse de latence et de bande passante.
Décision : Corrigez le profil de mémoire BIOS/compatibilité ; vérifiez le mix DIMM et les règles de population.
Task 4: See which CPUs are getting hammered by interrupts
cr0x@server:~$ cat /proc/interrupts | head -n 12
CPU0 CPU1 CPU2 CPU3 CPU4 CPU5 CPU6 CPU7
24: 18423922 0 0 0 0 0 0 0 IR-PCI-MSI 524288-edge nvme0q0
25: 12 0 0 0 0 0 0 0 IR-PCI-MSI 524289-edge nvme0q1
40: 9234411 0 0 0 0 0 0 0 IR-PCI-MSI 1048576-edge enp65s0f0-TxRx-0
41: 34 0 0 0 0 0 0 0 IR-PCI-MSI 1048577-edge enp65s0f0-TxRx-1
Signification : CPU0 se fait écraser par les queues NVMe et NIC. Cela corrèle souvent avec du jitter, des pics softirq, et « pourquoi un cœur est à 100 % ? »
Décision : Distribuez les IRQ : activez irqbalance (avec précaution), ou réglez manuellement l’affinité pour les queues critiques près du nœud NUMA du workload.
Task 5: Map a device to its NUMA node (NIC/NVMe locality)
cr0x@server:~$ cat /sys/class/net/enp65s0f0/device/numa_node
1
Signification : Cette NIC est locale au nœud NUMA 1.
Décision : Placez les threads de traitement réseau les plus chargés sur des CPU du nœud 1, et envisagez d’y lier les buffers/traitements réseau.
Task 6: Check PCIe link width/speed for “why is my NVMe slow?”
cr0x@server:~$ sudo lspci -s 41:00.0 -vv | egrep 'LnkCap:|LnkSta:'
LnkCap: Port #0, Speed 16GT/s, Width x4, ASPM L1, Exit Latency L1 <4us
LnkSta: Speed 8GT/s (downgraded), Width x4 (ok)
Signification : Le device peut faire 16GT/s mais tourne à 8GT/s. C’est un vrai impact sur le débit et la latence.
Décision : Vérifiez les réglages PCIe du BIOS, les risers, le câblage du slot et les retimers. N’« optimisez » pas le logiciel pour un problème de négociation matérielle.
Task 7: Verify CPU frequency behavior under load (power states matter)
cr0x@server:~$ sudo apt-get -y install linux-tools-common linux-tools-generic >/dev/null
cr0x@server:~$ sudo turbostat --quiet --Summary --interval 1 --num_iterations 3
Time_Of_Day_Seconds Avg_MHz Busy% Bzy_MHz IRQ SMI PkgTmp PkgWatt
54421.9 2875 62.3 4012 812 0 61 142.3
54422.9 2910 64.1 3988 799 0 62 145.0
54423.9 2842 60.8 4020 821 0 61 141.7
Signification : Vous voyez les MHz effectifs et les Bzy_MHz. Si Bzy_MHz s’effondre sous une charge modérée, les contraintes d’alimentation ou thermiques vous limitent.
Décision : Pour les services sensibles à la latence, sélectionnez un profil d’alimentation déterministe et envisagez de limiter les C-states profonds.
Task 8: Inspect per-NUMA-node memory allocation of a process
cr0x@server:~$ pidof memcached
24831
cr0x@server:~$ numastat -p 24831
Per-node process memory usage (in MBs) for PID 24831 (memcached)
Node 0 Node 1 Node 2 Node 3 Total
Huge 0.0 0.0 0.0 0.0 0.0
Heap 5120.0 1024.0 980.0 990.0 8114.0
Stack 8.0 8.0 8.0 8.0 32.0
Signification : Le heap est réparti sur les nœuds. Cela peut être acceptable pour le débit ; cela peut être catastrophique pour la latence tail si les threads sont majoritairement sur un nœud.
Décision : Liez le processus et sa mémoire à un nœud (ou segmentez par nœud). Ou exécutez explicitement plusieurs instances par nœud NUMA.
Task 9: Observe remote vs local memory accesses (kernel NUMA stats)
cr0x@server:~$ egrep 'numa_(hit|miss|foreign|interleave|local|other)' /proc/vmstat
numa_hit 428112233
numa_miss 2219921
numa_foreign 1941122
numa_interleave 0
numa_local 426331900
numa_other 1920333
Signification : numa_miss et numa_foreign montrent des allocations cross-node. Une montée rapide pendant un incident de latence est un drapeau rouge.
Décision : Enquêtez sur la migration de processus, le NUMA balancing automatique, et la politique mémoire. Corrigez le placement avant de changer le code.
Task 10: Confirm scheduler and cgroup CPU pinning (is the service drifting?)
cr0x@server:~$ systemctl show -p AllowedCPUs -p AllowedMemoryNodes myservice.service
AllowedCPUs=
AllowedMemoryNodes=
Signification : Vide signifie « pas de restriction ». Si vous attendiez un épinglage, il n’a pas lieu.
Décision : Ajoutez CPUAffinity/AllowedCPUs et des restrictions de nœuds mémoire, ou utilisez le cgroup cpuset pour faire respecter le placement.
Task 11: Pin a benchmark to one NUMA node to measure locality impact
cr0x@server:~$ numactl --cpunodebind=1 --membind=1 bash -lc 'python3 - <
Signification : Test grossier de « touch memory ». Répétez avec différents bindings de nœud. Si les temps varient beaucoup, la localité compte pour votre classe de workload.
Décision : Si les variations sont importantes, concevez les déploiements autour du sharding NUMA ou d’un épinglage explicite.
Task 12: Measure interconnect/topology with hwloc (visualize the chiplets)
cr0x@server:~$ sudo apt-get -y install hwloc >/dev/null
cr0x@server:~$ lstopo-no-graphics | head -n 30
Machine (256GB total)
Package L#0
NUMANode L#0 (P#0 64GB)
L3 L#0 (32MB)
L2 L#0 (512KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0
PU L#0 (P#0)
PU L#1 (P#1)
NUMANode L#1 (P#1 64GB)
L3 L#1 (32MB)
L2 L#1 (512KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1
PU L#2 (P#16)
PU L#3 (P#17)
Signification : Vous pouvez voir les nœuds NUMA et les groupements L3. Sur les designs chiplet, ces groupements s’alignent souvent avec les frontières CCD/CCX.
Décision : Utilisez cette vue pour concevoir des ensembles de CPU pour les services : gardez les threads bavards dans le même domaine L3 quand c’est possible.
Task 13: Spot cross-die cache line bouncing with perf (lock contention hint)
cr0x@server:~$ sudo perf stat -e cycles,instructions,cache-misses,LLC-load-misses -p 24831 -- sleep 10
Performance counter stats for process id '24831':
38,112,004,991 cycles
52,984,222,101 instructions # 1.39 insn per cycle
812,113,992 cache-misses
204,113,100 LLC-load-misses
10.003221861 seconds time elapsed
Signification : Beaucoup de LLC misses et un IPC plutôt bas peuvent indiquer une pression mémoire. Associez ceci aux stats NUMA pour distinguer « limité par la mémoire » d’un « mauvais placement ».
Décision : Si les LLC misses augmentent quand les threads sont répartis sur des nœuds, ré-épinglez ; si les misses sont inhérents, repensez la disposition des données ou la stratégie de cache.
Task 14: Check for Linux automatic NUMA balancing behavior
cr0x@server:~$ cat /proc/sys/kernel/numa_balancing
1
Signification : 1 signifie que le NUMA balancing automatique est activé. Il peut aider les charges générales, mais il peut aussi provoquer des migrations imprévisibles pour les services sensibles à la latence.
Décision : Si vous faites un épinglage explicite, envisagez de le désactiver (systémique ou via isolation de workload) et mesurez avant/après.
Task 15: Verify transparent hugepages status (latency vs throughput trade)
cr0x@server:~$ cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
Signification : THP est toujours actif. Cela peut être bon pour le débit, mais peut ajouter des pics de latence pendant la collapse/defrag sur certains workloads.
Décision : Pour les services sensibles à la latence tail, testez avec THP=never ou madvise et décidez sur la base du p99, pas de la moyenne.
Task 16: Check memory bandwidth saturation quickly (vmstat + mpstat)
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 8123456 123456 987654 0 0 1 3 900 2200 45 8 45 2 0
8 0 0 8012345 123456 988000 0 0 0 0 1100 5200 62 10 28 0 0
9 0 0 7999999 123456 987900 0 0 0 0 1200 6000 65 11 24 0 0
7 0 0 7988888 123456 987800 0 0 0 0 1180 5900 64 10 26 0 0
Signification : Beaucoup de threads en exécution (r) avec peu d’iowait (wa) suggère une pression CPU/mémoire plutôt que stockage. Associez à perf/numastat pour voir si c’est saturation de bande passante ou latence.
Décision : Si le CPU est occupé mais l’IPC est bas et les misses NUMA augmentent, corrigez le placement ; sinon envisagez de réduire la concurrence ou d’améliorer le comportement du cache.
Trois mini-histoires d’entreprise issues du terrain
Mini-histoire 1 : L’incident causé par une mauvaise hypothèse
Une équipe a déplacé une API sensible à la latence d’un ancien hôte Intel à double socket vers une machine EPYC mono-socket. Le plan de migration était simple :
« Mêmes cœurs, même RAM, moins de sockets, donc ça doit être plus simple. » Leur test de charge avait l’air ok — au début.
En production, non. Le p95 tenait, le p99 a grimpé, et l’astreinte a reçu la combinaison d’alertes classique : latence de requête élevée, utilisation CPU normale, pas de saturation I/O évidente.
Le tableau de bord avait l’air calme comme une forêt silencieuse juste avant que vous réalisiez que vous êtes perdu.
La mauvaise hypothèse était de traiter « un socket » comme « uniforme ». Le service avait un gros cache en mémoire et quelques mutex très chauds.
L’ordonnanceur a joyeusement migré les threads à travers les nœuds NUMA à l’intérieur du socket, les allocations mémoire ont dérivé, et les lignes de cache ont rebondi sur le fabric.
La latence moyenne ne criait pas. La latence tail, oui.
Le correctif était ennuyeux mais décisif : épingler le service à un nœud NUMA, lier la mémoire à ce nœud, et exécuter deux instances au lieu d’une grosse instance.
Ils ont aussi déplacé les interruptions NIC sur le même nœud. Le p99 s’est stabilisé. L’équipe a appris une nouvelle forme d’humilité : l’humilité topologique.
Élément d’action du postmortem qui a compté : ajouter des vérifications NUMA et d’affinité IRQ à la checklist de readiness, pas à la page wiki « tuning avancé » que personne ne lit.
Mini-histoire 2 : L’optimisation qui a mal tourné
Un service lourd en stockage (penser : métadonnées, checksums, compression) était limité par le CPU pendant les pics. Quelqu’un a proposé un changement simple :
« Répartissons les threads workers sur tous les cœurs pour maximiser le parallélisme. » Ils ont aussi activé un auto-scaling agressif basé sur le CPU, parce que bien sûr.
Le débit s’est amélioré dans les micro-benchmarks. Les graphes étaient en fête. Puis le job batch hebdomadaire a frappé, et tout est parti en vrille :
les délais de mise en file ont augmenté, le p99 a doublé, et le système a agi comme s’il avait un générateur de nombres aléatoires dans l’ordonnanceur.
Le retour de bâton venait de la contention cross-die. Étaler les workers sur les CCD a augmenté le parallélisme, oui, mais cela a aussi augmenté le trafic d’état partagé.
La queue « globale » et quelques tables de hachage partagées sont devenues des hotspots de cohérence. L’interconnect a fait son travail ; le workload l’a puni pour être coopératif.
Le correctif était contre-intuitif si vous ne croyez qu’aux nombres de cœurs : réduire le bavardage inter-die en sharding les queues par nœud NUMA et en épinglant les pools de workers.
Certains workers sont devenus inactifs, et l’utilisation CPU totale a chuté. La latence s’est améliorée. Le débit est resté acceptable. Les graphes sont devenus moins excitants,
ce que vous voulez en production.
La vraie leçon : sur les CPU chiplet, « plus de cœurs » n’est pas synonyme de « plus d’état partagé bon marché ». Si votre algorithme suppose un partage bon marché, vous tenez une grenade par la goupille.
Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une autre organisation exploitait une flotte mixte : stations de travail Ryzen pour CI et serveurs EPYC pour la production. Ils avaient une habitude qui semblait douloureusement terne :
chaque nouveau lot de matériel passait un run standardisé de validation topologique, et les résultats étaient attachés à la fiche d’actif.
Un trimestre, un lot de serveurs est arrivé avec une subtil mésconfiguration BIOS fournie par le vendeur : interleaving mémoire et profil d’alimentation favorisant
l’efficacité plutôt que la latence déterministe. Rien n’était « cassé ». Rien n’a échoué au POST. Les machines ont même passé le burn-in basique.
Mais leur run de validation l’a détecté : la latence mémoire était plus élevée que le lot précédent, et sous charge le comportement de fréquence était incohérent.
Comme ils avaient des baselines, ils avaient la preuve. Ils n’ont pas argumenté sur des impressions ; ils ont argumenté sur des mesures.
Ils l’ont corrigé avant la production : ajustement des profils BIOS, standardisation du firmware, et re-run des tests. Le lot a rejoint la flotte discrètement.
Pas d’incident. Pas de réunion d’urgence. Pas d’archéologie nocturne « pourquoi le p99 dérive ? »
La pratique ennuyeuse gagne parce qu’elle scale. Les héroïques ne le font pas. Si vous voulez de la fiabilité, institutionnalisez les vérifications inglamour.
Erreurs courantes : symptôme → cause racine → fix
1) Symptom: p99 latency spikes while CPU% looks fine
Cause racine : les threads migrent entre nœuds NUMA ; les allocations mémoire deviennent distantes ; le trafic de cohérence augmente entre CCDs/IOD.
Fix : épingler CPU et mémoire (cpuset/numactl), sharder par nœud NUMA, et valider avec numastat -p et les compteurs NUMA de /proc/vmstat.
2) Symptom: one core is pegged, softirq is high, network latency is jittery
Cause racine : affinité IRQ effondrée sur un seul CPU (souvent CPU0), ou queues mal configurées.
Fix : distribuer les interruptions, aligner les queues avec la localité NUMA, vérifier avec /proc/interrupts et le NUMA node du device dans sysfs.
3) Symptom: NVMe throughput is lower than expected after hardware change
Cause racine : lien PCIe négocié à une vitesse inférieure, mauvais slot, ou réglage BIOS limitant la vitesse du lien.
Fix : vérifier lspci -vv LnkSta vs LnkCap ; corriger slot/riser/BIOS ; retester avant de toucher aux paramètres de système de fichiers.
4) Symptom: performance varies run-to-run with same workload
Cause racine : NUMA balancing automatique, dérive de l’ordonnanceur, ou différents patterns d’allocation initiaux.
Fix : faire respecter le placement ; désactiver/ajuster le NUMA balancing pour le service ; valider en répétant un benchmark épinglé.
5) Symptom: “More threads” reduces throughput
Cause racine : contention cross-die sur les verrous ; queues partagées ; ping-pong de lignes de cache.
Fix : sharder l’état par nœud NUMA/CCD ; réduire les verrous globaux ; utiliser des pools de workers par nœud ; mesurer les LLC misses et la contention sur les verrous.
6) Symptom: stable throughput, but periodic long stalls
Cause racine : collapse/defrag THP, reclaim mémoire, ou transitions fréquence/alimentation.
Fix : tester THP=never/madvise ; assurer suffisamment de marge ; définir des profils d’alimentation déterministes pour les systèmes sensibles à la latence.
7) Symptom: database looks “CPU bound” but IPC is low
Cause racine : en réalité limité par la latence mémoire ; mémoire distante ; mauvaise localité à travers les chiplets.
Fix : épingler et lier la mémoire ; déplacer les données les plus chaudes vers des layouts favorables au cache ; mesurer avec perf + stats NUMA.
Listes de contrôle / plan pas à pas pour des déploiements compatibles chiplet
Plan pas à pas : admission d’un nouveau nœud Ryzen/EPYC
- Inventaire topologique : enregistrez
lscpu, le nombre de nœuds NUMA, le nombre de cœurs/threads. - Valider la population mémoire : utilisez
dmidecode; confirmez la vitesse attendue et les canaux équilibrés. - Baseline du comportement NUMA : capturez
numactl --hardware, la matrice de distances et les tailles mémoire par nœud. - Baseline du comportement de fréquence : mesurer sous charge avec
turbostatet enregistrer les plages « normales ». - Valider les liens PCIe : vérifier la vitesse/largeur négociée des NIC et NVMe avec
lspci -vv. - Confirmer la localité des devices : enregistrer le NUMA node via sysfs pour les NIC et NVMe principaux.
- Définir la stratégie IRQ : décider irqbalance vs affinité manuelle ; documenter et tester.
- Définir le placement des workloads : décider quels services doivent être épinglés et lesquels peuvent flotter.
- Établir un test : exécuter un test de touch mémoire ou de bande passante épinglé par nœud et stocker les résultats.
- Déployer graduellement : canary avec des workloads représentatifs ; surveiller p99 et les misses NUMA.
Checklist : quand un hôte chiplet a une latence inexpliquée
- Avons-nous des nœuds NUMA inattendus ou des tailles de mémoire de nœud inégales ?
- Les IRQ sont-elles concentrées sur un petit ensemble de CPU ?
- La NIC/NVMe est-elle sur un nœud NUMA différent des threads les plus chargés ?
- Le lien PCIe est-il négocié à une vitesse inférieure ?
- numa_miss/numa_foreign augmentent-ils pendant l’incident ?
- L’ordonnanceur est-il autorisé à migrer le service entre nœuds ?
- Les réglages firmware ou BIOS ont-ils changé (profil d’alimentation, interleaving mémoire, SMT) ?
Checklist : concevoir pour des performances prévisibles
- Sharder par nœud NUMA lorsque l’état est volumineux et l’accès fréquent.
- Garder les IRQ locales au calcul qui gère les paquets et les complétions I/O.
- Éviter les verrous globaux qui forcent le trafic de cohérence inter-die.
- Privilégier une concurrence bornée plutôt que « utiliser tous les cœurs » quand le p99 compte.
- Benchmarker avec et sans épinglage pour voir la sensibilité à la topologie.
FAQ
1) Les chiplets sont-ils toujours plus rapides que les CPU monolithiques ?
Non. Les chiplets gagnent souvent sur le prix/performance et la scalabilité. Les designs monolithiques peuvent l’emporter sur la latence uniforme et certains schémas de partage cache-cohérent.
Choisissez en fonction du comportement du workload, pas des adjectifs marketing.
2) Quelle est la différence opérationnelle la plus importante avec les CPU chiplet ?
La topologie devient une fonctionnalité de performance. La conscience NUMA et des domaines de cache compte dans des endroits où auparavant vous pouviez vous en dispenser.
3) Pourquoi AMD a-t-il séparé calcul et I/O sur des dies différents ?
Parce que c’est économiquement et techniquement sensé : les cœurs CPU bénéficient des nœuds de pointe ; l’I/O bénéficie des nœuds matures et d’un comportement analogique stable.
Les séparer améliore les rendements et réduit le risque par génération.
4) Quelle est la « taxe chiplet » la plus courante dans les systèmes réels ?
Les accès mémoire distants et le rebond de lignes de cache inter-die. Les deux apparaissent comme de la latence tail, pas nécessairement comme une baisse moyenne.
5) Dois-je désactiver SMT sur Ryzen/EPYC pour la latence ?
Parfois. SMT peut améliorer le débit mais peut aggraver la latence tail quand la contention est élevée ou quand vous êtes déjà sensible à la topologie.
Mesurez avec une charge proche de la production ; ne faites pas de cargo-cult.
6) Le NUMA balancing automatique est-il bon ou mauvais ?
Bon pour les hôtes à usage général. Risqué pour les services épinglés et sensibles à la latence car il peut migrer des pages de façon à créer du jitter.
Si vous épinglez explicitement, envisagez de le désactiver pour ces hôtes ou services — après mesure.
7) Pourquoi deux systèmes Ryzen « identiques » benchmarkent différemment ?
Raisons courantes : population mémoire différente (canaux), profils d’alimentation BIOS différents, réglages de couplage fabric/mémoire différents,
problèmes de négociation PCIe, et états différents de l’ordonnanceur/affinité IRQ.
8) Comment les chiplets affectent-ils les workloads de stockage spécifiquement ?
Les piles de stockage mélangent CPU, mémoire et PCIe. Si vos NVMe et NIC interruptions tombent loin des threads effectuant compression/checksums,
vous payez une latence supplémentaire et un surcoût de cohérence. Alignez la localité des devices, l’affinité IRQ et le placement des workers.
9) Les chiplets rendent-ils la virtualisation plus difficile ?
Pas plus difficile, mais moins indulgents. Si vous sur-allouez et laissez flotter les vCPU à travers des domaines NUMA, vous pouvez obtenir des effets voisin bruyant et un p99 imprévisible.
Un placement VM conscient du NUMA et l’épinglage CPU aident.
10) Que dois-je mettre en baseline sur chaque nouvelle plateforme chiplet ?
Topologie NUMA et distribution mémoire, état des liens PCIe, comportement de fréquence sous charge, et un instantané de distribution des IRQ.
Si vous ne pouvez pas détecter la dérive, vous ne pouvez pas la prévenir.
Conclusion : prochaines étapes qui réduisent vraiment le risque
Les chiplets d’AMD ont ressuscité Ryzen en changeant l’équation de fabrication : dies de cœurs plus petits, meilleurs rendements, scalabilité modulaire et itération plus rapide.
Cette décision business s’est transformée en une réalité opérationnelle : la topologie fait désormais partie des performances, pas une note de bas de page.
Prochaines étapes à entreprendre cette semaine, pas « un jour » :
- Choisissez un service sensible à la latence et mesurez aujourd’hui le placement NUMA :
numastat -p, compteurs NUMA de/proc/vmstat, et/proc/interrupts. - Canarisez une stratégie d’épinglage : liez CPU + mémoire à un nœud, alignez les IRQ, comparez le p99. Gardez le changement petit et mesurable.
- Institutionnalisez un test d’admission matériel : topologie, vitesses mémoire, négociation PCIe, et un check de sanity fréquence.
- Cessez de faire confiance aux moyennes : les problèmes de performance liés aux chiplets sont souvent des problèmes tail déguisés en moyenne.
Les chiplets ne sont pas un piège. C’est un deal : vous obtenez beaucoup de cœurs à un prix raisonnable, et en retour vous acceptez de traiter la topologie comme réelle.
Signez le contrat. Votre p99 vous remerciera.