Des monolithes aux chiplets : pourquoi les CPU modernes ressemblent à des LEGO

Cet article vous a aidé ?

Le ticket d’incident commence toujours de la même façon : « la latence p99 a doublé après la mise à jour ; l’utilisation CPU est plus faible qu’avant ; rien n’a de sens. »
Vous vous connectez à la nouvelle flotte et découvrez que le « CPU » n’est plus une seule chose. C’est une petite ville : plusieurs dies, plusieurs contrôleurs mémoire,
plusieurs caches et un interconnect qui gère les embouteillages aux heures de pointe entre eux.

Les chiplets n’ont pas seulement changé la façon dont les CPU sont fabriqués. Ils ont changé aussi ce que « même modèle de CPU » signifie en production. Si vous achetez, planifiez et optimisez comme en 2012,
vous aurez des surprises de niveau 2012—juste plus rapides et plus coûteuses.

Pourquoi les CPU sont devenus des LEGO

« Monolithique » était autrefois un compliment. Un seul die, un seul package, une hiérarchie de cache unique, un seul ensemble de règles.
On pouvait faire comme si le silicium était une surface plane où n’importe quel cœur pouvait atteindre n’importe quel octet de mémoire à peu près au même coût.
Cette fiction est morte pour les mêmes raisons que la plupart des belles théories : l’argent, la physique et la planification.

Un CPU à chiplets est construit à partir de plusieurs petits dies (chiplets) assemblés dans un même package.
Certains chiplets contiennent les cœurs CPU et les caches. Un autre peut contenir les contrôleurs mémoire et l’I/O (PCIe, USB, SATA, CXL).
Les chiplets communiquent via un interconnect sur le package.
Le résultat est modulaire : les fournisseurs peuvent mixer des blocs de construction plutôt que de retaper un énorme et fragile morceau de silicium.

Pensez aux chiplets moins comme « plusieurs CPU dans un manteau » et plus comme une carte mère miniature de sous-systèmes rétrécie dans un seul package.
Vous gagnez en échelle et en flexibilité, mais vous gagnez aussi en topologie. Et la topologie est l’endroit où les performances deviennent impressionnantes ou deviennent un ticket d’incident.

Faits intéressants et contexte historique (ce qui explique le bazar d’aujourd’hui)

  • Les grands dies ont des courbes de rendement brutales. À mesure que la surface du die augmente, la probabilité qu’un défaut le rende inutilisable monte ; les chiplets maintiennent les dies plus petits et les rendements plus élevés.
  • Les modules multi-dies ne sont pas nouveaux. Emballer plusieurs dies dans un module existe depuis des décennies, mais la bande passante d’interconnexion moderne le rend courant.
  • La « logique de liaison » est devenue une fonctionnalité. Les premières approches multi-die étaient souvent vues comme des compromis ; aujourd’hui les fournisseurs conçoivent autour délibérément.
  • Les contrôleurs mémoire sont passés sur die dans les années 2000. Cela a aidé la latence, mais a aussi préparé la scène pour NUMA et la complexité de topologie par socket.
  • L’emballage 2,5D (interposeur en silicium) a changé la donne. Il a permis des liaisons haute bande passante entre dies sans la pénalité habituelle d’un niveau PCB.
  • HBM a rendu la pensée chiplet naturelle. La mémoire à haute bande passante empilée sur le package a poussé tout le monde à traiter l’emballage comme une partie de l’architecture.
  • Les chiplets permettent de mixer les nœuds de processus. Les cœurs CPU peuvent être gravés sur un nœud dernier cri, tandis que l’I/O reste sur un nœud mature, meilleur pour l’analogique et moins cher.
  • Des efforts de standardisation existent, mais la réalité est bordélique. L’industrie veut des chiplets interopérables ; les fournisseurs livrent encore d’abord des écosystèmes fortement intégrés.

Blague #1 : Si la simplicité des CPU monolithiques vous manque, vous pouvez toujours la trouver dans la nature—à l’intérieur d’un organisme unicellulaire, aussi appelé votre environnement de staging.

Les chiplets en pratique : CCD, IOD, tiles et interconnexions

Les fournisseurs diffèrent dans leur marketing, mais le schéma est cohérent : séparer les parties calcul hautes performances de la plomberie.
Le calcul adore le nœud de processus le plus récent (transistors rapides, caches denses). L’I/O préfère les nœuds stables (bonnes caractéristiques analogiques, tolérance haute tension, wafers moins chers).

Blocs de construction courants

  • Chiplets de calcul : cœurs CPU et leurs caches proches (L1/L2) plus une tranche de cache partagé (souvent L3).
  • Die I/O (IOD) : contrôleurs mémoire, contrôleurs PCIe/CXL, routeurs de fabric, parfois des accélérateurs intégrés.
  • Interconnect : le réseau sur package qui permet aux chiplets de partager mémoire et cohérence de cache. Il définit vos coûts « locaux » et « distants ».
  • Substrat / interposeur du package : le medium physique qui transporte les signaux. Plus il est avancé, plus il peut agir comme un petit backplane haute vitesse.

Ce que vous gagnez

Vous gagnez en flexibilité manufacturière. Si un chiplet de calcul est défectueux, vous jetez ce petit die, pas un gigantesque monolithe.
Vous pouvez aussi construire une gamme de produits en peuplant le package avec différents nombres de chiplets de calcul—même I/O die, même socket, SKU différent.

Ce que vous payez

Vous payez en latence et en « non-uniformité ». Deux cœurs peuvent avoir la même microarchitecture, mais pas la même distance à la mémoire.
Une ligne de cache peut résider dans la tranche L3 d’un autre chiplet. Un thread peut zigzaguer entre chiplets si le planificateur ou votre appli est négligent.

En termes d’opérations : les chiplets sont une machine à débit qui peut devenir une machine à latence de queue si vous ne respectez pas la localité.

L’économie : rendement, binning, et pourquoi les grands dies pénalisent

Les chiplets ne sont pas d’abord une histoire de performances. C’est une histoire business avec des conséquences sur les performances.
Le levier le plus important du coût des semi-conducteurs est combien de dies bons vous obtenez par wafer.
Le coût du wafer augmente avec les nœuds avancés ; les défauts ne diminuent pas poliment.

Rendement, simplifié (sans trop mentir)

Un wafer a une densité de défauts. Un die a une surface. Une plus grande surface augmente la probabilité qu’un défaut intersecte le die.
C’est pourquoi les grands dies monolithiques sont chers avant même le conditionnement : vous jetez plus de silicium.

Avec des chiplets, vous acceptez que certains chiplets soient mauvais et d’autres bons, et vous assemblez les bons en produits.
Vous pouvez aussi trier (bin) les chiplets selon la fréquence ou la consommation atteignable. Le résultat est une utilisation plus efficace de ce que la fonderie produit.

Pourquoi mixer les nœuds est de l’ingénierie pratique, pas juste de la comptabilité

Les nœuds de pointe sont excellents pour la logique dense et les caches, mais ils ne sont pas automatiquement meilleurs pour tous les circuits.
Les PHYs et les blocs analogiques se comportent souvent mieux sur des nœuds matures. De plus : les nœuds matures peuvent avoir une meilleure disponibilité chaîne d’approvisionnement.
Quand l’I/O die reste sur un nœud mature, vous réduisez le risque et pouvez continuer à livrer même si la capacité des nœuds de pointe est contrainte.

Le point à retenir pour les achats : « même socket » n’implique plus « même performance ». Deux SKU peuvent partager un nom et une plateforme,
mais le nombre de chiplets, la disposition du cache ou la révision de l’I/O die peuvent changer le comportement d’une manière que vos benchmarks ne détecteront pas à moins d’examiner.

Réalité des performances : latence, bande passante et topologie

Les chiplets font ressembler le package CPU à un petit système NUMA plutôt qu’à une dalle uniforme.
Même à l’intérieur d’un socket, vous pouvez avoir plusieurs domaines mémoire, plusieurs îlots L3 et un fabric entre eux.
Votre goulot d’étranglement n’est souvent pas le « CPU » mais le « CPU plus l’endroit où se trouvent les données ».

Latence : la taxe que vous payez quand les données sont « là-bas »

La sensibilité à la latence apparaît d’abord sur les p95/p99. Les charges orientées débit peuvent la masquer avec du batching et du parallélisme.
Les services interactifs ne le peuvent pas. Si votre chemin de requête touche à un état partagé avec mauvaise localité, les chiplets feront rapidement apparaître ce coût.

Pièges de latence typiques :

  • Accès mémoire distant : un cœur charge depuis une mémoire attachée à un autre nœud NUMA ; c’est plus lent et souvent plus variable.
  • Trafic de cohérence inter-chiplet : le faux partage et les écritures fréquentes forcent l’interconnect à un travail imprévu.
  • Migration de thread : le planificateur déplace votre thread ; son working set chaud n’est plus dans les caches « proches ».

Bande passante : les chiplets peuvent être énormes, mais ce n’est pas infini

Un mode d’échec courant est de supposer que le fabric sur package est « essentiellement aussi bon » qu’un die monolithique.
Il est bon, mais ce n’est pas gratuit. Vous pouvez le saturer avec :

  • Des modèles de communication all-to-all (barrières, files partagées, verrous distribués).
  • Des charges qui copient beaucoup en mémoire (sérialisation, mise en tampon pour compression, chiffrement avec faible réutilisation de buffers).
  • Beaucoup de cœurs effectuant la même opération sur la même région mémoire.

Topologie du cache : le L3 n’est plus une piscine magique unique

De nombreux designs à chiplets exposent plusieurs tranches L3 avec un accès local plus rapide et un accès distant plus lent.
Votre appli ne voit pas « L3 = 96MB » comme un lac homogène ; elle voit un ensemble d’étangs reliés par des canaux.
Si votre working set chaud tient dans un étang mais que vous ramez constamment entre les étangs, vous allez quand même vous noyer.

Puissance et boost : les chiplets compliquent le « pourquoi c’est plus lent aujourd’hui ? »

Les CPU modernes jonglent avec le boost par cœur, les limites de puissance du socket, la température et parfois des limites par chiplet.
Ajouter des chiplets augmente le débit de pointe potentiel, mais vous ne pouvez pas toujours tout faire booster en même temps.
Rappel SRE : après une mise à jour, « plus de cœurs » peut signifier « moins de turbo par cœur en charge soutenue », ce qui change la latence.

Citation (idée paraphrasée) : Werner Vogels : construisez des systèmes en prévoyant les pannes, et concevez pour la résilience plutôt que de supposer que les composants se comporteront bien.

Blague #2 : Les chiplets sont comme les microservices—formidables jusqu’à ce que vous réalisiez que vous avez inventé un réseau, et que maintenant vous le déboguez à 5 h du matin.

Ce qui change pour les SRE et les équipes plateforme

Dans un monde monolithique, vous pouviez souvent vous en sortir avec « Linux va planifier » et « la base de données va gérer ».
Dans un monde de chiplets, les paramètres par défaut sont corrects, mais ils ne sont pas adaptés à votre charge.
Si vous vous souciez de la latence de queue, vous devez gérer activement la localité : affinage CPU, allocation mémoire consciente de NUMA, affinité IRQ et réglages BIOS sensés.

Ce qu’il faut exiger des vendeurs et du service achats

  • Divulgation complète de la topologie : nombre de nœuds NUMA par socket, canaux mémoire par nœud, disposition des caches et classe de bande passante de l’interconnect.
  • Mapping SKU cohérent : si une révision mineure change l’I/O die ou le comportement mémoire, vous voulez des notes de version et du temps de validation.
  • Comportement de puissance en charge soutenue : les politiques de turbo comptent plus que les fréquences de base sur la fiche technique.

Ce qu’il faut exiger de votre organisation

  • Benchmarks représentatifs de la production : les benchmarks CPU synthétiques sont du divertissement, pas une preuve.
  • Planification de capacité consciente de la topologie : planifiez par nœud NUMA, pas seulement par socket.
  • Standards de planification et d’affectation : les orchestrateurs de conteneurs ont besoin d’orientations, pas d’espérances.

Tâches pratiques : commandes, sorties, ce que cela signifie et vos décisions

Ce sont des contrôles de qualité production. Exécutez-les sur un hôte avec la « régression de performance mystérieuse ».
Chaque tâche inclut une commande, une sortie typique, ce que signifie la sortie et la décision à prendre.

Task 1: Voir la topologie CPU et NUMA

cr0x@server:~$ lscpu
Architecture:                         x86_64
CPU(s):                               64
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
L3 cache:                             256 MiB

Signification : Un socket, mais quatre nœuds NUMA. C’est la localité à la manière chiplet. Votre « socket unique » se comporte comme un petit multiprocesseur.

Décision : Traitez cet hôte comme NUMA. Pinglez les services sensibles à la latence sur un nœud et allouez la mémoire localement.

Task 2: Vérifier les distances NUMA (à quel point le « distant » est réel)

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: 64000 MB
node 0 free: 52210 MB
node distances:
node   0   1   2   3
  0:  10  20  20  28
  1:  20  10  28  20
  2:  20  28  10  20
  3:  28  20  20  10

Signification : Tous les nœuds distants ne se valent pas. « 28 » est notablement pire que « 20 ». Certains chiplets sont plus éloignés.

Décision : Pour une latence stricte, gardez threads et mémoire dans le même nœud ; pour du travail distribué, préférez les paires « plus proches ».

Task 3: Confirmer que le kernel voit la bonne politique NUMA

cr0x@server:~$ cat /proc/sys/kernel/numa_balancing
1

Signification : L’équilibrage NUMA automatique est activé. Il peut aider les charges générales, mais il peut aussi provoquer des migrations de pages et des pics de latence.

Décision : Pour un service critique en latence, envisagez de désactiver au niveau hôte ou cgroup et gérez explicitement l’affinité.

Task 4: Vérifier le comportement actuel des fréquences CPU (boost vs throttling)

cr0x@server:~$ sudo turbostat --Summary --quiet --show Busy%,Bzy_MHz,PkgWatt,PkgTmp
Busy%  Bzy_MHz  PkgWatt  PkgTmp
72.18   3045     245.7     88

Signification : Sous charge, les cœurs tournent en moyenne ~3.0 GHz, la puissance package est élevée, la température est proche des limites.

Décision : Si le p99 est pire que la génération précédente, vérifiez le refroidissement, les plafonds de puissance et les réglages BIOS avant d’accuser le code.

Task 5: Détecter la pression sur la bande passante mémoire

cr0x@server:~$ sudo perf stat -a -e cycles,instructions,cache-misses,LLC-load-misses,LLC-store-misses sleep 10
 Performance counter stats for 'system wide':

  38,220,118,992      cycles
  52,908,331,407      instructions              #    1.38  insn per cycle
   1,182,220,114      cache-misses
     992,110,332      LLC-load-misses
      88,330,901      LLC-store-misses

      10.001024001 seconds time elapsed

Signification : Un nombre élevé de miss LLC suggère que la charge déborde du cache et tape la mémoire (ou les lignes de cache distantes).

Décision : Enquêter sur la localité : pinglez les threads, réduisez le partage inter-threads, et validez l’allocation mémoire par nœud NUMA.

Task 6: Identifier la pression sur le planificateur et les runqueues (les threads rebondissent-ils ?)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0 (server)  01/10/2026  _x86_64_  (64 CPU)

12:04:18 AM  CPU   %usr   %sys  %iowait  %irq  %soft  %idle
12:04:19 AM  all  58.12   9.44    0.05   0.10   0.65  31.64
12:04:19 AM   0  92.00   6.00    0.00   0.00   0.00   2.00
12:04:19 AM  16  12.00  18.00    0.00   0.00   1.00  69.00
12:04:19 AM  32  86.00   9.00    0.00   0.00   0.00   5.00
12:04:19 AM  48  14.00  22.00    0.00   0.00   2.00  60.00

Signification : Certains CPU sont chauds, d’autres sous-utilisés, et certains montrent un temps système élevé. Cela peut indiquer un déséquilibre IRQ ou un mauvais pinning.

Décision : Vérifiez l’affinité IRQ et assurez-vous que vos threads de service sont épinglés de manière cohérente pour éviter les migrations entre chiplets.

Task 7: Inspecter la distribution des IRQ (un goulot caché classique)

cr0x@server:~$ cat /proc/interrupts | head
           CPU0       CPU1       CPU2       CPU3
  24:  98211233          0          0          0   PCI-MSI 524288-edge      eth0-TxRx-0
  25:         0          0          0          0   PCI-MSI 524289-edge      eth0-TxRx-1
  26:         0          0          0          0   PCI-MSI 524290-edge      eth0-TxRx-2
  27:         0          0          0          0   PCI-MSI 524291-edge      eth0-TxRx-3

Signification : Un seul cœur gère presque toutes les interruptions du NIC. Le chiplet local de ce cœur peut devenir le « chiplet réseau » par accident.

Décision : Activez irqbalance ou réglez l’affinité explicitement pour répartir les interruptions sur les cœurs prévus (et idéalement dans le même nœud NUMA que le NIC).

Task 8: Vérifier la localité des périphériques PCIe (quel nœud NUMA possède le NIC/NVMe)

cr0x@server:~$ cat /sys/class/net/eth0/device/numa_node
2

Signification : Le NIC est attaché au nœud NUMA 2. Si votre pile réseau tourne sur le nœud 0, vous effectuez des accès mémoire distants et de la gestion DMA distante.

Décision : Pinglez les threads réseau lourds sur le nœud 2 (ou déplacez les IRQ) et allouez les buffers sur le nœud 2 quand c’est possible.

Task 9: Confirmer que la mémoire est réellement locale au service

cr0x@server:~$ numastat -p 12345
Per-node process memory usage (in MB) for PID 12345 (myservice)
Node 0          1200.3
Node 1           980.1
Node 2          8200.7
Node 3           410.2
Total          10791.3

Signification : Le processus est majoritairement sur le nœud 2, mais a encore des allocations significatives sur d’autres nœuds—accès inter-nœuds potentiels.

Décision : Si ce service est sensible à la latence, serrez l’affectation CPU et mémoire (systemd, cgroups, taskset, numactl) pour éviter l’étalement.

Task 10: Vérifier l’activité de migration de pages (effets secondaires de l’équilibrage NUMA)

cr0x@server:~$ grep -E 'pgmigrate|numa' /proc/vmstat | head -n 10
pgmigrate_success 1822331
pgmigrate_fail 1122
numa_pte_updates 998122
numa_hint_faults 288111
numa_hint_faults_local 201994
numa_pages_migrated 155002

Signification : Le kernel migre activement des pages. Cela peut être bon pour le débit, mais ajouter du jitter et de la contention.

Décision : Si vous observez des pics de latence en queue, essayez de contrôler explicitement le placement et réduisez la dépendance à la migration automatique.

Task 11: Vérifier l’état des huge pages (pression TLB vs fragmentation)

cr0x@server:~$ grep -E 'HugePages|Hugepagesize' /proc/meminfo
HugePages_Total:       2048
HugePages_Free:        1980
HugePages_Rsvd:          12
Hugepagesize:        2048 kB

Signification : Des huge pages sont disponibles et majoritairement libres ; votre service peut ne pas les utiliser, ou il peut en réserver quelques-unes.

Décision : Pour les services mémoire-intensifs, validez si les huge pages réduisent les miss TLB ; ne les activez pas aveuglément si l’allocation devient fragmentée entre nœuds NUMA.

Task 12: Valider les CPU sets de cgroup pour une charge containerisée

cr0x@server:~$ systemctl show myservice --property=CPUQuota --property=AllowedCPUs --property=AllowedMemoryNodes
CPUQuota=400%
AllowedCPUs=0-31
AllowedMemoryNodes=0-1

Signification : Le service est limité aux CPU 0–31 et aux nœuds mémoire 0–1. Si le NIC/NVMe est sur le nœud 2, vous venez de créer une machine à accès distant.

Décision : Alignez CPU et nœuds mémoire avec la localité des périphériques. Placez le service là où son I/O vit ou déplacez les périphériques/IRQ en conséquence.

Task 13: Test rapide mémoire local vs distant (vérification ponctuelle)

cr0x@server:~$ sudo numactl --cpunodebind=0 --membind=0 bash -c 'dd if=/dev/zero of=/dev/null bs=1M count=4096'
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 0.642 s, 6.7 GB/s
cr0x@server:~$ sudo numactl --cpunodebind=0 --membind=3 bash -c 'dd if=/dev/zero of=/dev/null bs=1M count=4096'
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 0.811 s, 5.3 GB/s

Signification : Le binding mémoire distant réduit le débit observé. Les applis réelles paient aussi une latence supplémentaire, pas seulement une perte de bande passante.

Décision : Si le binding distant change significativement les chiffres, vous avez une charge sensible à la localité. Traitez le placement comme une exigence de première classe.

Task 14: Inspecter les indices de cache et la topologie depuis sysfs

cr0x@server:~$ for c in 0 16 32 48; do echo "cpu$c:"; cat /sys/devices/system/cpu/cpu$c/cache/index3/shared_cpu_list; done
cpu0:
0-15
cpu16:
16-31
cpu32:
32-47
cpu48:
48-63

Signification : Chaque groupe de 16 CPU partage un L3—quatre « îlots » L3. C’est une frontière chiplet/tranche de cache que vous devriez respecter.

Décision : Pinglez les threads coopérants dans un même îlot L3. Gardez les pools de threads bavards ensemble ; placez les voisins bruyants sur des îlots différents.

Guide de diagnostic rapide : trouvez le goulot avant de vous disputer sur l’architecture

Quand un service régresse sur des CPU à l’ère des chiplets, le chemin le plus rapide n’est pas un débat microarchitectural profond.
C’est un triage discipliné : topologie, localité, puissance, puis code.

Première étape : confirmez ce qu’est réellement la machine

  • Topologie : exécutez lscpu et numactl --hardware. Si nœuds NUMA > 1 par socket, traitez comme sensible à la topologie.
  • Îlots de cache : vérifiez les groupes L3 partagés via sysfs (Task 14). Cela prédit souvent mieux les pénalités inter-chiplet que les noms marketing.
  • Localité des périphériques : vérifiez le numa_node du NIC/NVMe dans sysfs. Les périphériques ancrés à un nœud peuvent tirer toute votre charge en distant.

Deuxième étape : identifiez si la douleur est latence, bande passante ou planification

  • Latence / jitter : regardez p95/p99 vs la moyenne. Si la moyenne va bien et que la queue est catastrophique, suspectez migration, mémoire distante, déséquilibre IRQ ou limitation de puissance.
  • Bande passante : utilisez perf stat pour les miss LLC, surveillez les explosions de cache-miss sous charge. Vérifiez aussi la saturation des canaux mémoire si vous avez des outils fournisseurs.
  • Planification : utilisez mpstat -P ALL. Des cœurs chauds et des cœurs froids suggèrent des problèmes de pinning, des hotspots IRQ ou une distribution de travail inégale.

Troisième étape : validez la politique et le placement

  • Équilibrage NUMA : vérifiez /proc/sys/kernel/numa_balancing et les statistiques de migration dans /proc/vmstat.
  • cgroups / cpusets : assurez-vous que CPU et nœuds mémoire sont alignés avec l’I/O du service.
  • Affinité IRQ : confirmez que les interruptions sont réparties et locales au nœud du périphérique.

Quatrième étape : seulement ensuite, ajustez ou refactorez

  • Si la localité est le problème : pinglez les threads, imposez une politique mémoire, restructurez les allocations.
  • Si c’est la bande passante : réduisez le churn d’état partagé, évitez le faux partage, réduisez les memcpy, regroupez, et envisagez des changements de stratégie de compression/chiffrement.
  • Si c’est la puissance : corrigez le refroidissement, les limites de puissance et les réglages BIOS ; n’« optimisez » pas le code pour compenser un problème thermique.

Erreurs courantes (symptômes → cause → correctif)

1) Symptom : la latence p99 a régressé après un refresh CPU, mais la latence moyenne s’est améliorée

Cause racine : Migrations inter-chiplet et accès mémoire distants causent du jitter en queue.

Correctif : Pinglez les threads de traitement des requêtes dans un îlot L3 ; liez la mémoire au même nœud NUMA ; réduisez la migration de threads (affinité, moins de threads exécutables que de cœurs, évitez les pools surdimensionnés).

2) Symptom : « CPU utilisé à seulement 40% » pourtant le débit plafonne

Cause racine : La bande passante mémoire ou celle du fabric est saturée ; des cœurs supplémentaires n’aident pas quand on est limité par la bande passante.

Correctif : Utilisez perf stat pour confirmer les cache-miss ; réduisez les chemins qui copient ; profilez le comportement de l’allocateur ; augmentez la localité ; envisagez du sharding par NUMA.

3) Symptom : un service réseau montre un cœur à 100% de temps système

Cause racine : L’affinité IRQ concentre les interruptions sur un CPU ; le périphérique est sur un nœud NUMA différent des threads du service.

Correctif : Répartissez les IRQ sur les cœurs du nœud NUMA du périphérique ; alignez le cpuset du service sur le même nœud ; vérifiez avec /proc/interrupts et sysfs.

4) Symptom : les performances varient énormément entre hôtes apparemment identiques

Cause racine : Les réglages BIOS diffèrent (limites de puissance, interleaving mémoire, SMT, réglages NUMA) ; des différences de stepping modifient le comportement de topologie.

Correctif : Standardisez les profils BIOS ; suivez les versions de firmware ; validez avec un test de fumée topology/perf court pendant la mise à disposition.

5) Symptom : la base de données ralentit en ajoutant des threads de travail

Cause racine : Contention sur les verrous et rebonds de lignes de cache entre chiplets ; faux partage dans files/counters partagés.

Correctif : Limitez les threads par îlot L3 ; shardez les données chaudes par nœud NUMA ; utilisez des compteurs par cœur/par nœud avec agrégation périodique.

6) Symptom : le service containerisé « thrash » la mémoire et se bloque « au hasard »

Cause racine : Le cpuset autorise des CPU sur un nœud, mais les allocations mémoire atterrissent ailleurs via les valeurs par défaut, la migration de pages ou des allocations partagées de l’hôte.

Correctif : Définissez à la fois les politiques CPU et nœuds mémoire dans les cgroups ; vérifiez avec numastat -p ; envisagez de désactiver l’équilibrage NUMA automatique pour cette charge.

Trois mini-histoires d’entreprise à l’ère des chiplets

Mini-histoire 1 : L’incident causé par une mauvaise hypothèse

Une équipe plateforme a déployé un nouveau serveur « mono-socket, grand nombre de cœurs » pour remplacer d’anciens machines double-socket. L’argument était simple :
moins de sockets signifie moins de problèmes NUMA, et la puce avait assez de cœurs. Le plan de migration traitait chaque hôte comme un pool uniforme de CPU.

En une semaine, une API client a commencé à expirer par rafales. Pas une saturation constante—des rafales. Les graphes étaient exaspérants :
l’utilisation CPU semblait saine, le taux d’erreur a grimpé, et ajouter des instances aidait moins que prévu.
L’ingénieur on-call a fait les vérifications habituelles : GC, base de données, réseau.
Rien d’évident.

Le déclic est venu des vérifications de topologie. Le « socket unique » exposait quatre nœuds NUMA. Le NIC était sur le nœud 2.
L’orchestrateur avait épinglé les pods sur les CPU 0–31 (nœuds 0 et 1) parce que c’était le cpuset par défaut de l’image hôte.
Les interruptions réseau étaient aussi concentrées sur un CPU du nœud 2. Le système faisait une danse compliquée :
les paquets arrivaient sur le nœud 2, étaient traités par un cœur IRQ sur le nœud 2, mis en file dans une mémoire pas toujours locale,
puis les threads travailleurs sur les nœuds 0/1 récupéraient le travail à distance. Le trafic inter-nœuds plus le jitter de planification rendait le p99 terrible.

La correction fut ennuyeuse : aligner les cpusets et les nœuds mémoire sur la localité du NIC, répartir les IRQ sur ce nœud, et garder les threads de requête proches de leurs buffers.
Le service s’est stabilisé. La leçon principale du postmortem était aussi ennuyeuse : « socket unique » n’est pas synonyme de « mémoire uniforme ». Sur les systèmes chiplet, ça ne l’a jamais été.

L’action de suivi qui a compté : l’équipe a ajouté une grille de provisioning qui refusait les hôtes où le numa_node du périphérique ne correspondait pas au cpuset prévu.
Pas glamour, mais ça a empêché une répétition.

Mini-histoire 2 : L’optimisation qui s’est retournée contre eux

Une équipe pipeline données a optimisé un hot path en augmentant le parallélisme. Ils ont pris un job batch à 32 threads workers et l’ont « mis à l’échelle »
à 128 threads sur la nouvelle génération de CPU à grand nombre de cœurs chiplet. Leur raisonnement était classique : plus de cœurs, plus de threads, plus de débit.

Le premier benchmark était bon—brièvement. Sur des runs courts le débit augmentait. Sur des runs longs, le débit se dégradait et devenait bruyant.
Les performances agrégées du cluster devenaient inconsistantes, et le temps mur du job n’améliorait plus.
Pendant ce temps, d’autres services sur les mêmes hôtes commençaient à se plaindre de la latence alors que « ce n’est qu’un job batch ».

L’analyse racine montra une pression sur l’interconnect et la mémoire, pas une saturation CPU. La charge avait une file de travail partagée
et quelques compteurs globaux mis à jour fréquemment. Sur un die monolithique, c’était agaçant mais tolérable.
Sur une topologie chiplet avec plusieurs îlots L3, cela devint un générateur de trafic de cohérence.
Ajoutez des migrations de threads et vous obtenez exactement ce que les compteurs perf prédisaient : beaucoup de cache misses, beaucoup de bavardage inter-nœuds.

Le « fix » fut de réduire le parallélisme, pas de l’augmenter. Ils ont plafonné les threads par îlot L3 et introduit des files et compteurs par nœud.
Le job utilisait moins de threads mais finissait plus vite et arrêtait d’embêter le reste du nœud.
La leçon douloureuse : les CPU de l’ère chiplet punissent les designs d’état partagé négligents. Lancer plus de threads n’est pas du scaling ; c’est une stratégie de déni.

Après, l’équipe changea sa grille d’évaluation : toute optimisation qui augmente le partage entre threads doit inclure un benchmark conscient de la topologie,
sinon elle ne passe pas. Ils ont aussi cessé de célébrer « l’utilisation CPU a augmenté » comme une victoire. L’utilisation n’est pas le débit, et encore moins la latence de queue.

Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Un groupe infrastructure gérait une flotte mixte : deux générations CPU, plusieurs versions BIOS, et un cadence de mises à jour firmware.
Ils n’étaient pas des héros. Ils étaient juste organisés.
Chaque hôte provisionné passait par une pipeline de burn-in qui collectait la topologie, la localité des périphériques, et un court ensemble de compteurs de performance sous charge.

Une semaine, ils remarquèrent un changement subtil : un sous-ensemble de nouveaux hôtes montrait des ratios d’accès mémoire distant plus élevés pour le même test de placement synthétique.
Les machines ne tombaient pas en panne, et personne n’avait ouvert de ticket. La pipeline l’a détecté parce que la baseline incluait la distance NUMA et un microbenchmark
épinglé local vs distant.

Le coupable était une dérive de profil BIOS. Un technicien bien intentionné avait utilisé un preset « performance » du fournisseur qui changeait l’interleaving mémoire.
Cela n’a pas cassé la machine ; ça a juste modifié les caractéristiques de localité suffisamment pour impacter les services sensibles à la latence.
Sans la pipeline de burn-in, cela serait arrivé sous la forme de « régressions aléatoires » des semaines plus tard.

Ils ont rollbacké le profil, ré-imagé une poignée d’hôtes, et ont continué. Pas de panne, pas de réunions d’urgence.
La pratique qui les a sauvés n’était pas géniale. C’était la cohérence : traitez la topologie et la localité comme une dérive de configuration, et testez-la comme vous testez la santé des disques.

Listes de vérification / plan pas à pas

Checklist : adopter les CPU de l’ère chiplet sans créer un cauchemar de latence

  1. Inventaire de la topologie : enregistrez les nœuds NUMA par socket, les groupes L3 partagés, les canaux mémoire et les nœuds NUMA des périphériques.
  2. Définir les classes de charge : critique latence, débit, batch, fond bruyant. Tout ne reçoit pas les mêmes règles de placement.
  3. Choisir une politique de placement :
    • Critique latence : pinglez dans un seul îlot L3 et un seul nœud NUMA.
    • Débit : shardez par nœud NUMA ; scalmez horizontalement si les données sont partitionnables.
    • Batch : isolez sur des nœuds/cores spécifiques ; limitez les hogs de bande passante.
  4. Aligner la localité I/O : placez les services réseau ou NVMe intensifs sur le nœud NUMA attaché à ces périphériques.
  5. Standardiser BIOS et firmware : un profil, version tracée, changements déroulés via des canaris.
  6. Valider le comportement de puissance : vérifiez les fréquences soutenues sous votre charge réelle, pas seulement « il booste une fois ».
  7. Construire un test de fumée : exécutez un test local-vs-remote mémoire et une capture courte de compteurs perf pendant le provisioning.
  8. Enseigner à votre planificateur : encodez les politiques cpuset/mems dans les unités systemd ou les labels/ specs de pods de l’orchestrateur.
  9. Documenter les modes de défaillance : déséquilibre IRQ, mémoire distante, contention verrous inter-nœuds, throttling thermique.
  10. Déployer avec canaris : comparez p99, pas seulement le débit. Exigez des critères de rollback.

Pas à pas : corriger une régression de localité sur un hôte en production

  1. Exécutez lscpu et numactl --hardware ; notez les nœuds, plages CPU, distances.
  2. Trouvez la localité des périphériques NIC/NVMe via sysfs numa_node.
  3. Vérifiez la distribution IRQ (/proc/interrupts) et corrigez l’affinité si un cœur est surchargé.
  4. Vérifiez le cpuset et la politique de nœuds mémoire du service (propriétés systemd ou fichiers cgroup).
  5. Utilisez numastat -p pour confirmer que l’allocation mémoire du service correspond à son placement CPU.
  6. Désactivez l’équilibrage NUMA automatique pour ce service si cela provoque de la migration ; retestez le p99.
  7. Limitez les pools de threads pour tenir dans un îlot L3 quand c’est possible ; évitez la contention inter-îlots.
  8. Relancez un court test de charge et comparez p50/p95/p99 ainsi que les compteurs perf.

FAQ

1) Les chiplets sont-ils toujours plus lents que les CPU monolithiques ?

Non. Les chiplets offrent souvent un meilleur débit, plus de cœurs, un cache agrégé plus grand et une meilleure économie. Ils sont « plus lents » seulement lorsque votre charge
paie des taxes d’accès distant et du trafic de cohérence que vous n’avez pas prévu—typiquement visible sur la latence de queue.

2) Pourquoi ne pas simplement rendre l’interconnect si rapide que ça n’a plus d’importance ?

À cause de la physique et de la puissance. Piloter des signaux haute vitesse coûte de l’énergie et génère de la chaleur. De plus, la latence est tenace ; on achète plus facilement de la bande passante que du temps aller-retour.

3) NUMA est-ce la même chose que chiplets ?

Pas identique, mais ils riment. NUMA est le modèle de performance : le temps d’accès mémoire dépend de quel contrôleur mémoire possède la page.
Les chiplets sont une approche d’emballage/architecture qui crée souvent plusieurs domaines mémoire et îlots de cache même à l’intérieur d’un socket.

4) Si Linux voit un socket, pourquoi devrais-je m’en soucier ?

Parce que « socket » est une étiquette comptable. Linux peut toujours exposer plusieurs nœuds NUMA et des groupes de caches séparés.
Votre charge se préoccupe de l’endroit où résident les pages mémoire et quels cœurs partagent le cache, pas du nombre de sockets physiques.

5) Dois-je tout pinner sur des CPU maintenant ?

Pas tout. Le pinning est un outil, pas une religion. Utilisez-le pour les services critiques en latence, le réseau à haut débit et tout ce qui a une forte localité de cache.
Pour des charges sans état générales, la planification par défaut peut suffire—jusqu’à ce que vous constatiez une dérive du p99.

6) Quelle est la plus grosse erreur que font les équipes pendant les refreshs ?

Supposer que le nouveau CPU est juste « l’ancien CPU mais plus rapide ». Les chiplets changent la topologie, le comportement du cache et la dynamique de puissance.
Si vous ne mesurez pas la localité et les fréquences soutenues sous votre charge, vous faites un refresh au feeling.

7) Plus de cache L3 signifie moins de problèmes ?

Plus de cache aide, mais la topologie compte. Si le cache est partitionné en îlots et que vos threads rebondissent entre les îlots, vous pouvez toujours manquer « plus souvent que prévu ».
Utilisez les groupes L3 partagés comme frontière de placement.

8) Comment les chiplets affectent-ils la virtualisation et les conteneurs ?

Ils augmentent le coût d’un placement négligent. Les VM et conteneurs peuvent se retrouver avec des vCPU répartis sur des nœuds NUMA tandis que leur mémoire est ailleurs.
Corrigez cela avec des politiques CPU et mémoire (cpuset + mems), et validez avec numastat et des contrôles de topologie.

9) Les chiplets augmentent-ils les taux de panne ?

Pas intrinsèquement. Ils déplacent le risque : emballage et interconnects plus complexes, mais souvent de meilleurs rendements et binning.
Opérationnellement, la principale « panne » est l’imprévisibilité des performances, pas des défauts matériels bruts.

10) Que dois-je benchmarker pour comparer deux CPU à chiplets ?

Benchmarquez votre charge avec une concurrence réaliste, des tailles de données réalistes et un I/O réaliste. Enregistrez le p99, pas seulement la moyenne.
Enregistrez aussi la topologie (distances NUMA, partage L3) pour pouvoir expliquer les différences plutôt que d’en débattre.

Prochaines étapes réalisables cette semaine

Les chiplets ne sont pas une mode. Ils sont la voie par défaut pour augmenter le nombre de cœurs et mixer les nœuds de processus. Se battre contre ça, c’est comme lutter contre la gravité :
vous pouvez le faire brièvement, mais vous n’aurez pas l’air malin en réunion d’incident.

  1. Ajoutez la topologie à vos facts hôtes : stockez lscpu, numactl --hardware, groupes L3 partagés et nœuds NUMA des périphériques dans votre inventaire.
  2. Rendez le placement explicite : pour un service critique en latence, implémentez le binding CPU et mémoire et documentez le raisonnement.
  3. Auditez l’affinité IRQ sur vos hôtes les plus chargés. Si un seul cœur supporte le monde, corrigez et prenez la victoire facile.
  4. Créez un test de fumée local vs distant pendant le provisioning pour que la dérive BIOS et les steppings étranges soient détectés avant le trafic prod.
  5. Réécrivez un hotspot d’état partagé : remplacez un compteur/queue global par un sharding par NUMA ou par cœur, puis mesurez la latence de queue.

L’objectif n’est pas de devenir architecte CPU. C’est d’arrêter d’être surpris par la physique que vous pouvez mesurer en 30 secondes.
Les CPU chiplet ressemblent à des LEGO parce que la fabrication et l’économie l’ont exigé. Votre travail est de les exploiter comme s’ils étaient modulaires, parce qu’ils le sont.

← Précédent
Hype des PC IA vs véritables changements d’architecture : ce qui compte en 2026
Suivant →
WireGuard site-à-site : connecter deux bureaux sur Internet étape par étape

Laisser un commentaire