Cœurs marketing : quand un chiffre dans un nom trompe

Cet article vous a aidé ?

Vous achetez un serveur « 64 cœurs », basculez une charge sensible à la latence dessus et… rien n’accélère. En fait, c’est plus étrange : certaines requêtes filent, d’autres s’arrêtent,
et les tableaux de bord se contredisent. Quelqu’un demande « Sommes‑nous limités par le CPU ? » et soudain la moitié de la salle benchmarke pendant que l’autre moitié négocie avec les finances.

C’est là que le mot « cœur » cesse d’être un nom technique et devient un verbe marketing. Le chiffre dans le SKU n’est pas une garantie de débit,
de latence, ni même d’ordonnancement prévisible. C’est un indice. Parfois utile. Souvent un piège.

Ce que signifie réellement un « cœur marketing »

Un « cœur marketing » est ce que la page produit veut vous faire croire qu’exécutera votre code. Un vrai cœur est l’ensemble des ressources d’exécution qui
terminent effectivement vos instructions au rythme qui importe pour votre charge : débit, latence, comportement de queue, et isolation des pannes. Ces deux notions sont liées, mais pas identiques.

Dans les systèmes modernes, « nombre de cœurs » peut signifier l’un des éléments suivants selon qui parle :

  • Cœurs physiques (cœurs CPU distincts avec leurs propres pipelines et caches L1/L2 privés).
  • Threads matériels (SMT/Hyper‑Threading : deux ou plusieurs threads ordonnançables partageant les mêmes unités d’exécution).
  • Cœurs d’efficacité vs cœurs de performance (architectures hétérogènes où « un cœur » n’appartient même pas à la même catégorie).
  • vCPU (abstraction cloud ou de virtualisation qui peut correspondre à des threads matériels, des tranches de temps, ou un mix).
  • « Cœurs équivalents » (unités définies par le vendeur ou pour la licence visant à normaliser entre architectures, souvent avec des échecs comiques).

Votre travail, en tant que responsable de la disponibilité et des budgets, est de traduire le « nombre de cœurs » en performance réalisable pour votre charge :
débit, latence, comportement des queues, et isolation des pannes. Cela implique de comprendre la topologie, le comportement turbo, la bande passante mémoire, la hiérarchie de caches,
et la politique du planificateur — pas seulement de compter des choses.

Une autre vérité directe : les erreurs les plus coûteuses arrivent quand le comptage de cœurs est exact, mais sans rapport. Vous pouvez avoir des cœurs réels et être
limité par la latence mémoire, le réseau, le stockage, la contention sur les verrous, les pauses GC, ou la licence par cœur.

Pourquoi les chiffres dans un nom trompent (et comment)

1) SMT/Hyper‑Threading : doubler les « CPU » sans doubler la performance

Le SMT est une technologie légitime : il remplit les bulles d’exécution et améliore le débit sur de nombreuses charges. Ce n’est pas « deux cœurs. »
Ce sont deux threads matériels qui se disputent les mêmes unités d’exécution, les mêmes caches et souvent le même budget puissance/thermique.

Si votre charge sature déjà les ports d’exécution d’un cœur (fréquent dans les boucles serrées, le cryptage, la compression, certains opérateurs de BD), le SMT aide moins.
Si votre charge s’arrête sur la mémoire ou les mauvais prédictions de branchements, le SMT peut aider davantage. « Peut » fait beaucoup de travail ici.

L’élément trompeur : les tableaux de bord et les descriptions d’instances cloud comptent parfois les threads matériels comme CPU. Cela gonfle les chiffres et change les attentes.

2) Cœurs hétérogènes : les P‑cores et E‑cores ne sont pas interchangeables

Un « cœur » sur un CPU hybride peut être un cœur de performance (gros, large, rapide) ou un cœur d’efficacité (plus petit, plus lent, plus économe).
Le planificateur décide où vos threads atterrissent, et tous les planificateurs ne le font pas bien sous charge — surtout dans des environnements riches en conteneurs avec
limites CPU, affinités, ou noyaux anciens.

Si vous exécutez des services sensibles à la latence, vous vous souciez de l’ordonnancement en pire cas. Si vous exécutez des traitements par lots, vous vous souciez du débit global par watt.
« Nombre total de cœurs » mélange tout cela en un seul chiffre facile à afficher et difficile à raisonner.

3) Turbo, limites de puissance et fréquence « all‑core »

Les vendeurs aiment annoncer la fréquence turbo maximale. Ce chiffre est typiquement un meilleur cas pour un petit nombre de cœurs actifs sous conditions thermiques idéales.
Votre vie réelle est la « fréquence all‑core sous charge soutenue, en baie, dans une salle chauffée, après six mois de poussière. »

Le nombre de cœurs interagit avec la puissance. Beaucoup de CPU ne peuvent pas maintenir tous les cœurs à la même fréquence élevée simultanément. Ajoutez des instructions AVX coûteuses et vous verrez
peut‑être une chute supplémentaire de la fréquence. Votre achat « plus de cœurs » peut vous coûter une vitesse par cœur inférieure pour la charge exacte pour laquelle vous l’avez acheté.

4) NUMA : la taxe silencieuse sur « plus de sockets, plus de cœurs »

Ajoutez des sockets, et vous ajoutez des domaines NUMA. La mémoire attachée à un socket est plus lente d’accès depuis un autre socket. Cette pénalité se manifeste par une latence de queue plus élevée,
une amplification de la contention sur les verrous, et des mystères du type « c’est rapide en microbench mais lent en prod ».

NUMA n’est pas un bug ; c’est de la physique et du packaging. L’erreur est de supposer que votre logiciel est NUMA‑conscient quand il ne l’est pas.

5) vCPU cloud : un nombre qui peut signifier « thread matériel », « quota » ou « partage temporel »

Dans le cloud, vCPU correspond souvent à un thread matériel. Mais les caractéristiques de performance dépendent de la contention sur l’hôte, de la variabilité du modèle CPU,
et de la politique d’ordonnancement. Certaines familles d’instances vous donnent des cœurs dédiés ; d’autres vous donnent « principalement pour vous sauf si quelqu’un d’autre est bruyant ».

Le nommage implique souvent une base stable qui n’existe pas. Vous devez mesurer.

6) Licences : les « cœurs » comme unité de facturation, pas de calcul

La licence par cœur est l’endroit où les cœurs marketing deviennent des cœurs juridiques. Certains vendeurs comptent les cœurs physiques ; d’autres comptent les threads ;
certains appliquent des multiplicateurs selon la famille CPU ; d’autres ont des minima par socket. Votre achat peut se baser sur « plus de cœurs par dollar » puis découvrir que le logiciel double la facture.

Si vous exécutez des bases de données propriétaires, des moteurs d’analyse ou des piles de virtualisation, la licence peut dominer le coût matériel. « Nombre de cœurs » devient un problème budgétaire
avant d’être une caractéristique de performance.

Blague #1 : Une puce « 64 cœurs » ressemble à un paquet « format famille » de chips — techniquement vrai, mais ça ne vous dit pas à quel point ce sera satisfaisant.

Faits & contexte historique que vous pouvez utiliser dans des arguments

Voici des points courts et concrets à lâcher dans les réunions de dimensionnement pour éviter la pensée magique.

  1. Les « guerres du MHz » x86 ont pris fin quand la fréquence a heurté les limites de puissance et de chaleur. L’industrie s’est tournée vers le multicœur parce que les horloges n’augmentaient plus comme avant.
  2. Hyper‑Threading est apparu largement à l’époque des Intel Pentium 4. Il a amélioré le débit sur certaines charges, mais a aussi exposé des problèmes d’ordonnancement et de contention de cache.
  3. NUMA existe depuis des décennies dans les serveurs haut de gamme. Ce qui a changé, c’est que les boîtiers grand public ont eu plusieurs sockets et chiplets, apportant un comportement proche de NUMA aux parcs « ordinaires ».
  4. Les chiplets (CPU multi‑die) ont augmenté le nombre de cœurs plus vite que la bande passante mémoire. Plus de cœurs par socket ne signifie pas automatiquement plus de mémoire par cœur ou de bande passante par cœur.
  5. « Cœur » est devenu une unité de licence dans les logiciels d’entreprise bien avant d’être une unité de tarification cloud. C’est pourquoi certains termes de licence supposent encore sockets et cœurs physiques.
  6. Les instructions vectorielles larges comme AVX peuvent déclencher des réductions de fréquence. « Même CPU, mêmes cœurs » peut tourner plus lentement selon le mélange d’instructions.
  7. Les améliorations du planificateur Linux pour cœurs hétérogènes sont relativement récentes. La version du noyau compte quand vous mélangez P‑cores/E‑cores ou des designs type big.LITTLE.
  8. Les familles d’instances cloud cachent souvent la variation des modèles CPU derrière un même nom. Deux instances avec le même nombre de vCPU peuvent avoir un IPC et un comportement de cache très différents.
  9. Les benchmarks de type SPEC ont poussé les vendeurs à optimiser pour des charges spécifiques. Ce n’est pas de la triche ; c’est la réalité. Mais cela signifie que votre charge peut se comporter différemment des graphiques en tête d’affiche.

Modes de défaillance : comment les équipes se font piéger en production

« Comptage de cœurs trompeur » n’est pas une plainte théorique. Ça finit par des pages d’astreinte parce que les équipes dimensionnent les systèmes sur la mauvaise variable.
Voici les schémas qui reviennent dans les postmortems.

Le sophisme des cœurs égaux

Les équipes supposent que 32 cœurs sur le CPU A équivalent à 32 cœurs sur le CPU B. En réalité vous comparez peut‑être :
IPC différent, tailles de cache différentes, canaux mémoire différents, fréquence all‑core différente, et topologie différente.
« Mêmes cœurs » devient une régression de performance déguisée en achat.

La mauvaise lecture « CPU élevé »

Une utilisation CPU élevée n’est pas automatiquement « limitante CPU ». Vous pouvez être en train de boucler sur des verrous, de faire des retries, de compresser des logs parce que le stockage est lent,
ou d’exécuter du travail noyau à cause d’interruptions mal réparties. Le CPU est l’endroit où la douleur apparaît, pas toujours l’endroit où elle commence.

La confusion des quotas de conteneur

Dans Kubernetes, un pod peut être throttled par des limites CPU même lorsque le nœud est majoritairement inactif. Les développeurs voient un faible CPU nœud et supposent un reste de marge.
Pendant ce temps, la quota CFS étrangle silencieusement le débit et étire la latence en queue.

La surprise NUMA

Un service est « rapide sur de petites instances, lent sur les grandes. » C’est la signature NUMA. Les machines plus grandes ajoutent des domaines mémoire ; les threads de l’app
errent entre eux ; la localité cache meurt ; la latence explose. Plus de cœurs, pire comportement.

Le boomerang des licences

Quelqu’un choisit le SKU au plus grand nombre de cœurs pour « se prémunir » puis découvre que la licence de la base de données est facturée par cœur avec un minimum par socket.
La revue finance arrive. Soudain « future‑proof » devient « revenir en arrière et s’excuser ».

Trois micro‑histoires d’entreprise (anonymisées, douloureusement plausibles)

Micro‑histoire 1 : Un incident causé par une mauvaise hypothèse

Une société SaaS de taille moyenne a migré sa flotte d’API d’anciennes machines 16 cœurs vers de nouvelles machines 32 cœurs.
Les nouvelles boîtes coûtaient moins cher par cœur et affichaient une fréquence turbo plus élevée. Les achats étaient ravis ; l’équipe SRE était prudemment optimiste.

Dans la semaine, la rotation d’astreinte a commencé à voir des pics intermittents de latence en queue sur l’API, surtout lors des rafales de trafic.
Rien d’évident : le CPU moyen était à 40–60 %, la charge moyenne avait l’air « correcte », et il n’y avait pas de pics d’erreurs — juste des requêtes lentes et des clients mécontents.

L’équipe a supposé que « plus de cœurs » signifiait plus de concurrence. Ils ont donc augmenté le nombre de workers et élargi les pools de threads.
Ça a empiré les pics. Le service frappait parfois des timeouts internes et des tempêtes de retries, ce qui a encore gonflé le CPU.

La cause racine était un cross‑talk NUMA plus une pression sur la bande passante mémoire. Les nouvelles machines avaient plus de cœurs mais une configuration de canaux mémoire différente,
et la charge — parsing JSON intensif plus TLS plus un cache mémoire partagé — était sensible à la latence mémoire et à la localité de cache.
Les threads migraient entre nœuds NUMA, transformant des hits de cache en misses distants sous rafales.

Les corrections furent ennuyeuses et efficaces : pinner les pools de workers les plus chauds à un nœud NUMA, allouer la mémoire localement, et limiter la concurrence pour s’aligner sur la bande passante mémoire.
La flotte s’est stabilisée — mais avec une cible « cœurs utilisés » plus basse qu’avant. L’intitulé du postmortem : « Nous avons acheté des cœurs ; nous avions besoin de bande passante. »

Micro‑histoire 2 : Une optimisation qui s’est retournée

Une équipe plateforme données exécutait un service d’ingestion distribué qui compressait les payloads avant d’écrire dans l’object storage.
Ils sont passés d’un CPU 24 cœurs à un CPU 48 cœurs « plus de cœurs pour le même prix », en s’attendant à une mise à l’échelle linéaire de la compression.

Ils ont fait ce que font de bons ingénieurs : ils ont optimisé. Le niveau de compression a augmenté. Le parallélisme a augmenté. Les tampons ont été ajustés.
Le débit en benchmark mono‑nœud a augmenté proprement, et le changement a été déployé.

En production, la latence a explosé et le débit a chuté. Les nœuds accumulaient de la backpressure et un système aval commençait à timeout.
Le CPU était saturé, mais pas dans un sens « travail utile ». Les context switches étaient élevés. Les files d’exécution étaient longues. L’attente I/O était étrangement élevée.

La performance par cœur soutenue du nouveau CPU sous charge all‑core soutenue était plus faible que prévu à cause des limites de puissance et du mélange d’instructions.
Leur bibliothèque de compression utilisait des instructions vectorielles déclenchant des baisses de fréquence. Plus de threads a simplement forcé le CPU dans un état stationnaire plus lent.
Pire : le parallélisme additionnel produisait plus d’écritures plus petites et plus d’opérations métadonnées, créant une amplification I/O sur la chaîne de stockage.

Ils ont rollbacké l’« optimisation », puis l’ont réintroduite avec des contraintes : moins de threads de compression, regroupement des écritures, et un objectif
de fréquence all‑core stable plutôt que du turbo de pointe. La leçon : scaler une étape liée au CPU peut révéler et aggraver une étape liée à l’I/O,
et « plus de cœurs » peut être un raccourci vers un plateau de fréquence plus lent.

Micro‑histoire 3 : Une pratique ennuyeuse mais correcte qui a sauvé la situation

Une organisation de services financiers préparait une grosse mise à niveau de base de données. Le vendeur recommandait un serveur plus grand avec un nombre de cœurs supérieur.
L’équipe plateforme n’a pas discuté ; elle a simplement exécuté son prévol standard : capture de topologie, benchmark de référence, et confirmation des licences.

La capture de topologie montrait deux sockets, plusieurs nœuds NUMA par socket, et SMT activé. Les tests de base montraient que la charge était sensible à
la latence mono‑thread pour certaines requêtes et sensible à la bande passante mémoire pour les analytics. Elle n’était pas sensible au nombre brut de threads.

La vérification des licences montrait que la licence de la base était par cœur physique avec un minimum par socket et un multiplicateur selon la famille CPU.
Le « serveur avec plus de cœurs » aurait augmenté le coût de licence sensiblement sans améliorer les requêtes goulot d’étranglement.

Ils ont choisi un autre SKU : moins de cœurs, fréquence soutenue plus élevée, meilleure configuration mémoire, et topologie NUMA prévisible.
Ils ont aussi configuré le pinning CPU pour les processus les plus chauds et validé le plan avec une relecture des traces de production.

Rien de dramatique pendant la mise à niveau. Pas d’incident. Pas d’héroïsme nocturne. C’était si inaperçu que la direction a presque oublié l’opération,
ce qui est le plus grand compliment qu’une équipe ops puisse recevoir.

Tâches pratiques : commandes, sorties, décisions (12+)

L’objectif ici n’est pas de collectionner des trivia. L’objectif est d’arrêter de débattre sur la base des pages SKU et de commencer à prendre des décisions
à partir de la machine devant vous. Chaque tâche inclut : une commande, une sortie d’exemple, ce que ça signifie, et la décision qui en découle.

Task 1: Confirm what the OS thinks “CPUs” are

cr0x@server:~$ nproc
128

Ce que cela signifie : L’OS voit 128 CPUs ordonnançables (CPUs logiques). C’est généralement « cœurs physiques × threads SMT », mais ça peut aussi être contraint par un cpuset.

Décision : Traitez ce chiffre comme une surface d’ordonnancement, pas comme « 128 vrais cœurs ». Étape suivante : cartographier la topologie.

Task 2: Inspect CPU topology (cores, threads, sockets, NUMA)

cr0x@server:~$ lscpu | egrep -i 'Model name|Socket|Core|Thread|NUMA|CPU\(s\)'
CPU(s):                               128
Model name:                           AMD EPYC 7xx3 64-Core Processor
Thread(s) per core:                   2
Core(s) per socket:                   64
Socket(s):                            1
NUMA node(s):                         4

Ce que cela signifie : 64 cœurs physiques, SMT=2, un socket, mais quatre nœuds NUMA (layout chiplet). NUMA compte même sur un seul socket.

Décision : Pour les charges sensibles à la latence, planifier le pinning NUMA et des tests de localité mémoire. Pour les charges de débit, benchmarker la montée en charge par nœud NUMA.

Task 3: See which logical CPUs share a core (SMT siblings)

cr0x@server:~$ lscpu -e=CPU,CORE,SOCKET,NODE | head
CPU CORE SOCKET NODE
0   0    0      0
1   0    0      0
2   1    0      0
3   1    0      0
4   2    0      0
5   2    0      0
6   3    0      0
7   3    0      0
8   4    0      0

Ce que cela signifie : Le CPU 0 et 1 sont deux threads sur un même cœur physique, etc.

Décision : Si votre charge sature le cœur ou est critique pour la latence, envisagez de pinner un thread par cœur d’abord, puis d’étendre si utile.

Task 4: Check current CPU frequency behavior under idle

cr0x@server:~$ sudo apt-get -y install linux-tools-common linux-tools-$(uname -r) >/dev/null 2>&1
cr0x@server:~$ sudo turbostat --Summary --quiet --interval 1 --num_iterations 1
CPU     Avg_MHz   Busy%   Bzy_MHz  TSC_MHz  PkgWatt
-       1420      6.15    3220     3000     68.12

Ce que cela signifie : Sous faible charge, les cœurs occupés boostent (Bzy_MHz supérieur à Avg_MHz). Cela ne vous renseigne presque rien sur le comportement soutenu all‑core.

Décision : Si vous dimensionnez pour un débit soutenu, testez sous une concurrence et un mélange d’instructions représentatifs.

Task 5: Confirm CPU governor and energy policy

cr0x@server:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
performance

Ce que cela signifie : « performance » maintient une fréquence élevée. « powersave » (sur certains systèmes) peut aller, mais parfois il handicape la latence.

Décision : Pour les services à faible latence, préférer un comportement de fréquence prévisible. Pour des flottes batch, mesurer le compromis puissance vs débit.

Task 6: Measure per-core vs all-core scaling quickly (sanity test)

cr0x@server:~$ sudo apt-get -y install sysbench >/dev/null 2>&1
cr0x@server:~$ sysbench cpu --cpu-max-prime=20000 --threads=1 run | egrep 'events per second|total time'
events per second:   381.12
total time:          10.0004s
cr0x@server:~$ sysbench cpu --cpu-max-prime=20000 --threads=64 run | egrep 'events per second|total time'
events per second:   20112.47
total time:          10.0031s

Ce que cela signifie : Le scaling est correct ici, mais ne vous fiez pas trop : ce test est fortement compute‑bound et peut ne pas refléter votre mix production.

Décision : Utilisez‑le comme contrôle « la machine n’est pas cassée ». Pour décider, benchmarquez votre charge réelle ou rejouez des traces.

Task 7: Detect CPU throttling due to thermal/power limits

cr0x@server:~$ dmesg -T | egrep -i 'throttl|thermal|powercap' | tail -n 5
[Mon Jan 22 10:14:03 2026] intel_rapl_common: Found RAPL domain package
[Mon Jan 22 10:15:41 2026] CPU0: Core temperature above threshold, cpu clock throttled
[Mon Jan 22 10:15:42 2026] CPU0: Core temperature/speed normal

Ce que cela signifie : Un throttling est survenu. Cela transforme le « nombre de cœurs » en belle histoire tandis que la « performance réelle » devient une cible mouvante.

Décision : Corriger le refroidissement/airflow, vérifier les paramètres BIOS de puissance, et relancer des benchmarks soutenus. Ne pas tuner le logiciel sur une plateforme thermiquement instable.

Task 8: Check NUMA layout and free memory 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: 64000 MB
node 0 free: 51000 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 64000 MB
node 1 free: 12000 MB
node 2 cpus: 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
node 2 size: 64000 MB
node 2 free: 52000 MB
node 3 cpus: 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
node 3 size: 64000 MB
node 3 free: 50000 MB

Ce que cela signifie : Le nœud 1 est à l’étroit en mémoire comparé aux autres. Si votre processus se retrouve là, il peut allouer à distance et payer la latence.

Décision : Rééquilibrer l’usage mémoire, pinner les processus loin des nœuds contraints, ou corriger la stratégie d’allocateur/pinning.

Task 9: Verify whether your process is suffering remote NUMA allocations

cr0x@server:~$ pidof nginx
2142
cr0x@server:~$ sudo numastat -p 2142 | head -n 8
Per-node process memory usage (in MBs) for PID 2142 (nginx)
        Node 0  Node 1  Node 2  Node 3   Total
Huge       0.0     0.0     0.0     0.0     0.0
Heap     820.4   112.2   640.1    95.7  1668.4
Stack      8.2     1.1     6.3     0.9    16.5
Private  410.5    55.0   320.2    44.7   830.4

Ce que cela signifie : La mémoire est répartie sur les nœuds ; selon le placement CPU, certains accès sont distants.

Décision : Envisagez d’exécuter un groupe de workers par nœud NUMA, de pinner les ensembles CPU, ou d’utiliser numactl pour binder la mémoire des processus chauds.

Task 10: Observe run queue pressure and context switching

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  98124 9234560  0    0     3    17  680 1200 12  3 84  1  0
10  0      0 8119320  98124 9235104  0    0     0     0 2200 9000 55 10 34  1  0
18  1      0 8101000  98124 9238000  0    0     0   420 3500 15000 60 15 20  5  0

Ce que cela signifie : r (runnable) est élevé ; cs (context switches) pique. C’est souvent de la sur‑souscription ou de la contention sur des verrous, pas « on a besoin de plus de cœurs ».

Décision : Réduire le nombre de threads, inspecter les verrous, tuner les pools de workers, ou pinner les threads chauds. Acheter des cœurs n’est pas la première réparation.

Task 11: Confirm iowait isn’t masquerading as CPU limitation

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0 (server) 	01/22/2026 	_x86_64_	(128 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          22.10    0.00    6.90   18.40    0.00   52.60

Device            r/s     w/s   rkB/s   wkB/s  await  aqu-sz  %util
nvme0n1         120.0   880.0  7680.0 90240.0  12.4    9.20   96.0

Ce que cela signifie : %iowait élevé, %util du device élevé, et file croissante (aqu-sz) indiquent que le stockage est le goulot.

Décision : Arrêtez de blâmer les cœurs. Corrigez le stockage : réduire l’amplification d’écriture, augmenter la profondeur de file si adapté, ajouter du cache ou scaler le débit de stockage.

Task 12: Check IRQ distribution (a classic “CPU is high” lie)

cr0x@server:~$ cat /proc/interrupts | head -n 8
           CPU0       CPU1       CPU2       CPU3
  24:   9123456          0          0          0   IO-APIC   24-fasteoi   nvme0q0
  25:         0          0          0          0   IO-APIC   25-fasteoi   nvme0q1
  26:         0          0          0          0   IO-APIC   26-fasteoi   nvme0q2
  27:         0          0          0          0   IO-APIC   27-fasteoi   nvme0q3

Ce que cela signifie : Les IRQs s’entassent sur le CPU0 et peuvent créer des hotspots CPU artificiels et de la latence. Le device est « multi‑queue », mais les interruptions ne sont pas équilibrées.

Décision : Activer/vérifier irqbalance, configurer l’affinité d’interruptions, et revérifier la latence en queue avant de toucher au nombre de cœurs.

Task 13: See whether you’re being CPU-throttled by cgroups (containers)

cr0x@server:~$ cat /sys/fs/cgroup/cpu.stat 2>/dev/null || cat /sys/fs/cgroup/cpu/cpu.stat
usage_usec 932112345
user_usec  701223000
system_usec 230889345
nr_periods  14400
nr_throttled 3920
throttled_usec 412334500

Ce que cela signifie : Beaucoup de throttling (nr_throttled) et un temps significatif throttled : vous n’êtes pas « à court de cœurs », vous êtes à court de quota.

Décision : Augmenter la limite CPU, supprimer les limites pour les services sensibles à la latence, ou redimensionner requests/limits et la taille des nœuds.

Task 14: Compare “CPU time” vs “wall time” to detect contention

cr0x@server:~$ /usr/bin/time -v bash -c 'python3 - <

Ce que cela signifie : Pourcentage CPU proche de 100 % et temps mur égal au temps utilisateur suggèrent une exécution CPU propre. Si le temps mur est beaucoup plus grand, vous attendez — souvent sur des verrous ou de l’I/O.

Décision : Si le temps mur gonfle sous concurrence, investiguez la contention avant d’acheter plus de cœurs.

Feuille de route de diagnostic rapide : trouver le goulot vite

Quand un système « devrait être plus rapide parce qu’il a plus de cœurs » et ne l’est pas, vous avez besoin d’un chemin de triage rapide et reproductible.
Pas d’une semaine de théâtre de benchmarking.

First: prove what “cores” you actually have

  1. Topologie : lscpu pour sockets/cores/threads/nœuds NUMA.
  2. Pression mémoire NUMA : numactl --hardware et numastat.
  3. Throttling : vérifier dmesg pour événements thermiques/de puissance ; utiliser turbostat sous charge représentative.

Si vous ne pouvez pas décrire votre topologie en une phrase, vous n’êtes pas prêt à interpréter des graphiques perf.

Second: determine whether it’s CPU, memory, storage, or scheduling

  1. Saturation CPU vs contention : vmstat 1 (file d’exécution r, context switches cs).
  2. Attente I/O et saturation device : iostat -xz 1.
  3. Hotspots IRQ : /proc/interrupts et usage des files NIC/NVMe.
  4. Throttling cgroup : cpu.stat pour le temps throttled.

Le résultat visé : classer le goulot. « CPU à 70 % » n’est pas une classification.

Third: validate with one focused experiment

  • Pinner les threads (ou désactiver SMT pour une fenêtre de test) pour voir si la performance devient plus prévisible.
  • Changer la concurrence (moitié des workers) pour voir si le débit tient pendant que la latence s’améliore — signature classique de contention.
  • Déplacer la charge vers une génération CPU connue bonne et comparer le temps CPU par requête et la latence en queue.

Une expérience, une hypothèse, un plan de rollback. Vous faites de l’exploitation, pas de l’astrologie.

Citation (idée paraphrasée) : L’idée de John Ousterhout : mesurer et localiser le goulot avant d’optimiser — sinon vous changez du code pour le plaisir.

Erreurs courantes : symptôme → cause racine → correction

C’est la partie à coller dans les canaux d’incident quand les gens commencent à chanter « ajoutez des cœurs ».

1) Symptom: “CPU is low but latency is high”

  • Cause racine : throttling cgroup, déséquilibre de la file exécutable, ou stalls I/O. Le CPU au niveau nœud paraît inactif ; votre pod est étranglé par quota ou attend le stockage.
  • Correction : Vérifier le throttling via cpu.stat, supprimer les limites pour les services critiques en latence, et valider la saturation stockage via iostat.

2) Symptom: “New higher-core server is slower under load”

  • Cause racine : fréquence all‑core soutenue plus basse, throttling thermique/de puissance, ou downclocking induit par AVX.
  • Correction : Mesurer la fréquence all‑core avec turbostat sous charge représentative ; ajuster les limites BIOS et le refroidissement ; réduire la concurrence AVX si nécessaire.

3) Symptom: “Scaling stops at N threads and then gets worse”

  • Cause racine : contention sur verrous, bouncing de cache‑line, saturation bande passante mémoire, ou contention entre threads SMT.
  • Correction : Réduire le nombre de threads ; pinner un thread par cœur ; profiler les verrous ; répartir le travail par nœud NUMA ; envisager de désactiver SMT pour cette classe de charge.

4) Symptom: “Big instance is slower than small instance for the same service”

  • Cause racine : effets NUMA et allocations mémoire distantes ; le trafic cross‑node augmente la latence en queue.
  • Correction : Binder processus et mémoire avec placement NUMA‑aware ; exécuter plusieurs instances plus petites ; ou choisir un SKU avec moins de domaines NUMA.

5) Symptom: “One CPU core is pegged; others are idle”

  • Cause racine : affinité d’interruptions/déséquilibre IRQ, goulot mono‑thread, ou verrou global.
  • Correction : Vérifier /proc/interrupts ; activer irqbalance ; corriger le goulot mono‑thread ; sharder le verrou global ; arrêter de croire que « plus de cœurs » résout le travail sériel.

6) Symptom: “We upgraded cores, now storage got worse”

  • Cause racine : l’étape CPU s’est accélérée et a augmenté la concurrence I/O, exposant les limites de file de stockage et l’amplification d’écritures.
  • Correction : Limiter le débit des writers, batcher/regrouper l’I/O, tuner la profondeur de file, ajouter du cache, ou scaler le débit de stockage. Traiter CPU et stockage comme un système couplé.

Blague #2 : Si vous dimensionnez votre système uniquement par nombre de cœurs, vous choisissez essentiellement des pneus d’après le nombre de lettres dans le nom de la marque.

Listes de contrôle / plan étape par étape

Checklist A: Before you buy “more cores”

  1. Définir l’objectif : débit, latence médiane, latence p99, ou coût par requête. Choisir un objectif principal.
  2. Collecter des preuves du goulot : file d’exécution, iowait, throttling, et utilisation stockage.
  3. Capturer la topologie : sockets/cores/threads/nœuds NUMA et canaux mémoire (au moins les nœuds NUMA et la mémoire libre par nœud).
  4. Vérifier le modèle de licence : cœurs physiques vs threads ; minima par socket ; multiplicateurs selon famille CPU.
  5. Benchmark réaliste : concurrence représentative et mix d’instructions ; inclure caches chauds ; inclure réseau et stockage dans la boucle si pertinent.
  6. Décider du « type de cœur » nécessaire : haute performance mono‑thread vs beaucoup de cœurs ; risque d’ordonnancement sur cœurs hybrides ; valeur du SMT.

Checklist B: When performance is weird after a migration

  1. Vérifier l’absence de throttling : événements thermiques et de puissance dans les logs ; contrôle de fréquence soutenue.
  2. Vérifier le throttling cgroup : surtout si containerisé ; confirmer que les limites n’ont pas changé.
  3. Valider le placement NUMA : pinning CPU et localité mémoire pour les processus les plus chauds.
  4. Vérifier l’équilibre des interruptions : répartir les interruptions NIC et NVMe sur les CPU.
  5. Comparer le temps CPU par requête : si le temps CPU par requête a augmenté, vous êtes sur un cœur plus lent ou effectuez plus de travail.
  6. Comparer la latence stockage : un « CPU plus rapide » peut pousser le stockage plus fort ; ne pas confondre symptômes et causes.

Checklist C: If you must communicate this to non-engineers

  • Remplacer « cœurs » par « travail effectué par seconde ». Reliez‑le aux résultats business (requêtes/sec au p99 cible).
  • Utiliser un seul graphique : débit vs latence sous augmentation de la concurrence. Ça expose rapidement la contention et le throttling.
  • Expliquer NUMA comme « distance à la mémoire ». Les gens comprennent la distance.
  • Expliquer SMT comme « deux travailleurs partageant un même bureau ». C’est suffisamment précis pour éviter de mauvaises décisions.

FAQ

1) Are vCPUs the same as cores?

Généralement non. vCPU mappent souvent à un thread matériel, pas à un cœur physique, et leur performance dépend de la contention hôte et de la génération CPU.
Traitez le nombre de vCPU comme un quota d’ordonnancement, puis mesurez le débit et la latence réels.

2) Should I disable SMT/Hyper-Threading?

Ne le désactivez pas par superstition. Testez. Pour certaines charges sensibles à la latence ou lourdes en verrous, désactiver SMT peut améliorer la latence en queue et la prévisibilité.
Pour les charges de débit avec beaucoup de stalls, le SMT peut aider. Décidez au cas par cas selon la charge.

3) Why does a higher-core CPU sometimes have worse single-thread performance?

Parce que les budgets de conception sont finis : puissance, surface de die, cache et fréquence. Les CPUs optimisés pour la densité de cœurs peuvent avoir un comportement boost plus faible,
un cache par cœur plus petit, ou des horloges soutenues plus basses sous charge.

4) How do P-cores/E-cores affect servers and containers?

Les designs hybrides compliquent l’ordonnancement. Sans support noyau et politique correcte, les threads sensibles à la latence peuvent atterrir sur des cœurs plus lents.
Dans les conteneurs, le pinning et les limites CPU peuvent amplifier ces erreurs d’ordonnancement. Validez avec un pinning aware‑topology et des mesures de latence.

5) What’s the fastest way to tell if I’m CPU-bound?

Cherchez une utilisation élevée et un faible iowait, un contexte de commutation modéré, et une file d’exécution conforme aux attentes.
Si l’iowait est élevé ou si du throttling est présent, vous n’êtes pas « CPU‑bound » d’une manière que l’achat de cœurs résoudrait.

6) Why does performance get worse when I increase thread counts?

Contention. Plus de threads peuvent augmenter la compétition sur les verrous, le bouncing de cache‑line, la surcharge du planificateur, et la pression sur la bande passante mémoire.
Au‑delà d’un certain point, la machine passe son temps à coordonner le travail plutôt qu’à l’exécuter.

7) How does NUMA show up in symptoms?

Signes typiques : pics de latence p99 lors de rafales, utilisation CPU inégale par nœud NUMA, et performance qui se dégrade sur les machines « plus grosses ».
Des outils comme numastat peuvent montrer des allocations distantes ; le pinning stabilise souvent le comportement.

8) Is benchmark data from vendors useless?

Pas inutile — juste incomplet. Les benchmarks vendeurs peuvent indiquer des tendances, mais les goulots de votre charge peuvent être différents.
Utilisez les données vendeurs pour présélectionner, puis validez avec vos propres tests basés sur traces ou charges réelles.

9) How do I avoid per-core licensing surprises?

Traitez la licence comme une contrainte technique à part entière. Avant de choisir un CPU, confirmez ce qui compte comme cœur licenciable,
si SMT est compté, s’il y a des minima par socket, et si des multiplicateurs de famille CPU s’appliquent.

10) What’s the most reliable “core count” metric to use internally?

Pour les discussions d’ingénierie : rapportez séparément cœurs physiques, threads SMT, et nœuds NUMA. Pour la planification de capacité : utilisez « requêtes/sec au p99 cible »
sur un profil matériel défini. C’est la métrique qui résiste au marketing.

Conclusion : que faire ensuite

Arrêtez de traiter le chiffre dans le nom du CPU comme un SLA. « Plus de cœurs » est une capacité, pas une garantie — et parfois c’est une bombe budgétaire avec un dissipateur.
Si vous opérez des systèmes en production, votre travail est de transformer des noms marketing en réalité mesurée.

Étapes pratiques suivantes :

  1. Capturer la topologie pour chaque profil matériel que vous exécutez : sockets, cœurs physiques, threads SMT, nœuds NUMA.
  2. Construire une petite suite de benchmarks répétables : un test de sanity CPU, un test sensible à la mémoire, un test avec stockage dans la boucle, et un replay de trace si possible.
  3. Pour les plateformes conteneurs, vérifier routinièrement le throttling cgroup et l’équilibre des IRQ avant de « scaler up ».
  4. Lors de l’achat de matériel (ou d’instances), optimiser pour le goulot : latence mono‑thread, bande passante mémoire, latence stockage, ou coût de licence — pas le nombre de cœurs.

Faites cela, et « 64 cœurs » redevient une entrée d’ingénierie utile — une que vous pouvez utiliser sans vous réveiller à 3 h du matin.

← Précédent
Fuites IPv6 Docker : prévenir l’exposition « Oups, c’est public »
Suivant →
ZFS zpool initialize : faire en sorte que les nouveaux disques se comportent bien dès le premier jour

Laisser un commentaire