19 points par GN⁺ 2025-09-04 | 3 commentaires | Partager sur WhatsApp
  • En général, on évalue la limite de performance d’un serveur à partir du % d’utilisation CPU affiché par des outils de supervision comme top, mais en réalité cet indicateur ne reflète pas linéairement les performances
  • Des tests réalisés avec stress-ng sur un système équipé d’un Ryzen 9 5900X montrent qu’à 50 % d’utilisation, la charge de travail réelle atteint déjà 60 à 100 %, ce qui révèle un fort décalage avec l’indicateur
  • Les principales causes sont l’hyperthreading et le turbo boost, car le partage des ressources entre cœurs logiques et les variations de fréquence faussent la métrique
  • Il est donc plus pertinent de comparer un benchmark de la charge de travail réellement traitable au débit actuel traité, plutôt que de se fier à la seule utilisation CPU
  • Interpréter l’utilisation CPU de façon linéaire entraîne de grosses erreurs d’estimation des performances ; pour la planification des systèmes, une approche fondée sur des benchmarks est nécessaire

Écart entre le taux d’utilisation CPU d’un serveur et son débit réel

  • Lorsqu’on exploite un serveur, beaucoup veulent savoir s’il approche de son taux d’utilisation maximal
  • En général, on se réfère à la valeur la plus élevée parmi l’utilisation réseau, mémoire et CPU via des outils de supervision comme top
  • Mais en pratique, le chiffre d’utilisation CPU et la quantité de travail réellement traitable n’augmentent pas de manière linéaire

Environnement et méthode de test

  • Expérience menée sur un PC Ubuntu Desktop avec Ryzen 9 5900X (12 cœurs / 24 threads)
  • Precision Boost Overdrive (Turbo) activé
  • Simulation de diverses charges avec stress-ng (1 à 24 workers, 1 à 100 % d’utilisation)
  • Mesures observées : utilisation CPU rapportée par le système et volume réel de calcul (Bogo ops)

Résumé des résultats

  • Charge CPU générale : à 50 % d’utilisation, débit réel de 60 à 65 %
  • Opérations entières 64 bits : à 50 % d’utilisation, débit réel de 65 à 85 %
  • Calcul matriciel (Matrix math) : à 50 % d’utilisation, débit réel de 80 à 100 %
    • En réalité, même lorsque des workers supplémentaires n’apportent aucun gain de performance, l’utilisation CPU continue d’augmenter

Analyse des causes

  • Hyperthreading

    • Architecture composée de 12 cœurs physiques + 12 cœurs logiques
    • Jusqu’à 12 workers, le placement sur les cœurs physiques est optimal, mais au-delà, le partage des cœurs logiques dégrade les performances
    • En particulier pour les opérations SIMD (calcul matriciel), les ressources partagées ne permettent aucun gain de performance
  • Turbo boost

    • À faible charge, 4,9 GHz → en pleine charge, 4,3 GHz, soit une baisse de fréquence de 15 %
    • Cela fausse la formule de calcul de l’utilisation CPU (= busy cycles / total cycles)
      • Comme le dénominateur (nombre total de cycles) diminue, la hausse de l’utilisation est surestimée par rapport à la charge de travail réelle

Enseignements

  • L’utilisation CPU n’est pas un indicateur absolu de performance
  • Pour estimer la capacité d’un serveur et prévoir ses performances :
    • 1. Mesurer le débit maximal au moyen de benchmarks
    • 2. Surveiller le débit en temps réel
    • 3. Comparer les deux pour déterminer si l’on approche de la limite de performance
  • Selon l’architecture CPU (AMD vs Intel), l’efficacité de l’hyperthreading et le mode de fonctionnement du turbo, les écarts peuvent être importants, d’où la nécessité d’une analyse par processeur

Conclusion

  • L’utilisation CPU n’est rien d’autre que le rapport de cycles occupés, et ne reflète pas fidèlement les performances de traitement réelles
  • Avec une utilisation efficace, 50 % d’utilisation peuvent déjà correspondre à 80 à 100 % des performances maximales
  • En conséquence, la supervision des performances et la planification système doivent se concentrer sur le débit réel des charges de travail, fondé sur des benchmarks, plutôt que sur la seule utilisation CPU

3 commentaires

 
ifmkl 2025-09-07

Dans un environnement HPC réel, on désactive généralement l'hyperthreading par défaut lors de la configuration du cluster.

 
GN⁺ 2025-09-04
Commentaires sur Hacker News
  • Je ne pense pas que l'utilisation CPU soit un mensonge dans la mesure où elle mesure bien une grandeur clairement définie, mais dès que les gens essaient d'extrapoler à partir de ça pour construire un modèle de capacité, ils constatent un décalage entre la réalité et leurs attentes
    L'hyperthreading (SMT) et le Turbo (mise à l'échelle de la fréquence) ne sont que quelques-unes des nombreuses variables qui introduisent de la non-linéarité ; la bande passante mémoire partagée entre les cœurs, la capacité de l'interconnexion, les caches processeur, etc., sont aussi des ressources qui se « saturent » à mesure que la charge augmente
    Côté logiciel également, des phénomènes comme les spinlocks peuvent par exemple avoir un effet non linéaire sur l'utilisation
    La plupart des métriques d'utilisation CPU font des moyennes longues, de quelques secondes à une minute, alors que ce qui compte pour les performances des serveurs sensibles à la latence se joue en quelques dizaines ou centaines de millisecondes
    Du coup, une utilisation moyennée sur plusieurs secondes ne permet pas de distinguer un comportement en rafales d'un comportement lisse
    Mais l'approche proposée, à savoir « benchmarker combien de travail un serveur peut effectuer avant que des erreurs ou une latence inacceptable n'apparaissent », est elle aussi intrinsèquement instable
    Quand on cherche le point à partir duquel un serveur commence à devenir instable, les mesures deviennent très bruitées, et en théorie des files d'attente tout le bruit est amplifié à proximité du point critique
    Par ailleurs, la notion même de « quantité de travail que le serveur effectue en ce moment » est souvent définie de manière instable (RPS ? le coût varie selon les requêtes, et l'IPC varie aussi selon le moment)
    Au final, l'intervalle de confiance obtenu avec une approche de test de charge n'est pas si différent de celui d'un modèle empirique construit à partir de métriques d'utilisation. L'hypothèse de base reste qu'on mesure correctement l'utilisation

    • Si on sait utiliser perf ou ftrace, on peut obtenir sur une courte période des métriques processeur très détaillées et voir directement différentes causes comme les stalls CPU dus aux cache misses ou aux accès mémoire, l'impact de l'ordonnanceur, etc.
      Mais la plupart des gens, même si on leur donne des métriques comme l'IPC ou le taux de hit du cache, ne savent pas quoi en faire
      Au bout du compte, ce qui intéresse vraiment la plupart des gens, c'est la latence et l'utilisation
      En simplifiant grossièrement, pour la majorité des workloads, il n'y a pas vraiment de problème de latence tant que l'utilisation CPU ne dépasse pas 80 %
      Mais au-delà, cela commence à avoir un impact sérieux sur la latence du workload
      L'ampleur de cet impact sur la latence ne peut être connue qu'en mesurant directement son propre workload
      Le degré de sensibilité à la latence dépend aussi de l'organisation et de ses objectifs, et il peut arriver que l'optimisation du throughput soit plus importante
      Si l'on se soucie à la fois de la latence et du throughput, il faut mesurer les deux et décider soi-même du bon compromis

    • Je pense qu'un des points essentiels est justement que la définition même de la « quantité de travail » vacille
      Par exemple, ce n'est pas la même chose selon qu'on traite des requêtes d'utilisateurs réels sur un service public-facing, ou qu'on exécute en back-end un workload d'entraînement IA qui calcule tranquillement sur des données accumulées
      Ma façon de voir les choses est que, dans l'environnement moderne des CPU multicœurs avec hyperthreading, où les rafales sont inévitables, une utilisation CPU de 60 % suffit déjà à considérer un serveur comme « fortement chargé »
      Si elle reste au-dessus de 60 % pendant une part significative de la journée, j'estime qu'il est pertinent de répartir la charge (principalement pour les services qui répondent à des requêtes utilisateur)
      Par le passé, ce genre de critère amenait souvent à se poser la question de l'auto-scaling dans le cloud
      Aujourd'hui, on peut avoir des serveurs de plus de 100 cœurs pour autour de 30 000 $, donc la situation est plus complexe
      Aujourd'hui, je privilégierais plutôt une approche hybride consistant à surprovisionner légèrement le matériel des serveurs réels, puis à étendre au besoin via des services cloud (ou un cloud interne basé sur Kubernetes)
      À ses débuts, StackOverflow a exploité un trafic énorme de façon très efficace avec un rack dédié et un uplink à 10 Gbit/s, et aujourd'hui ce type d'exploitation est encore plus facile qu'à l'époque
      En conclusion, selon mes critères, si la charge CPU reste à 65 % pendant plus de 30 minutes, je considère déjà que l'utilisation est effectivement à 100 % et qu'une montée en charge s'impose rapidement

    • Le keynote de la récente conférence IEEE Hot Interconnects mentionnait aussi un cas de réglage de la latence sur Ultra Ethernet
      À l'échelle de 2 ou 5 secondes, tout peut sembler plat, mais si l'on regarde sur 100 ms, le phénomène de frame burst apparaît clairement
      Autrement dit, si la fenêtre de mesure du profiling n'est pas adaptée au workload réel, on peut tirer à tort une conclusion de faux négatif, ce qui aggrave encore le problème

    • Je suis entièrement d'accord avec ce point
      C'est le caractère non linéaire de l'utilisation CPU qui fait que le pourcentage lui-même se décale de la réalité
      En d'autres termes, l'affirmation est que seule l'utilisation CPU mesurée en % est mensongère

    • Si deux workloads affichent tous deux 100 % d'utilisation CPU, mais que l'un consomme beaucoup plus d'énergie et fait nettement monter la température du CPU, on peut se demander si, en réalité, ce workload n'utilise pas davantage de ressources transistorisées

  • Même si l'utilisation CPU n'est pas une mesure parfaite, elle a tout de même été utile en pratique
    Même dans une expérience simple d'exploitation SRE, pour des tâches CPU-bound, on a utilisé les chiffres d'utilisation CPU avec la théorie des files d'attente pour dimensionner les serveurs avant un événement de grande ampleur, et même avec un seuil de %CPU recommandé de façon beaucoup plus conservatrice qu'une approche plus « traditionnelle », le résultat a été bien plus rentable
    L'idée clé est que, même si une mesure est un peu imprécise, si elle est exploitable sur le terrain, il ne faut pas trop s'inquiéter et il faut s'en servir
    Cela dit, si l'utilisation CPU en production était toujours maintenue sous 40 %, c'était nécessairement pour conserver un peu de headroom dans diverses situations
    Je trouve dommage que l'auteur ne fournisse pas de fondement logique plus solide à l'idée qu'il faut « éviter les fortes utilisations du point de vue de la théorie des files d'attente »

    • Je pense qu'un indicateur un peu approximatif suffit largement s'il est utilisé de manière appropriée sur le terrain
      Par exemple, j'ai constaté qu'en pratique, utiliser simplement la moyenne ou le maximum des métriques en percentile par hôte, ou recalculer les percentiles lors de l'agrégation finale d'histogrammes au niveau des hôtes, ne changeait pas grand-chose dans l'exploitation réelle
      Certaines personnes se préoccupent énormément du fait qu'un calcul soit mathématiquement parfaitement correct ou non, mais dans l'exploitation réelle cela a parfois peu d'impact

    • 40 %, ça me semble en réalité une utilisation assez lâche, avec pas mal de marge

    • Je pense qu'en regardant ensemble le CPU% et le loadavg, on peut déjà assez bien comprendre l'état d'un système
      Si le loadavg est élevé mais le CPU% faible, on est peut-être bloqué sur le réseau ou les E/S, ou en attente sur des appels système
      Dans ce cas, regarder uniquement le CPU% risque de faire passer à côté de la vraie zone de souffrance

    • J'ai l'impression d'avoir déjà entendu exactement la même chose
      Il est étonnant que l'auteur écrive comme s'il venait de découvrir quelque chose qui est répété dans les livres de théorie des files d'attente depuis des décennies

  • Cela m'a rappelé l'article de Brendan Gregg, "CPU Utilization is Wrong"
    L'idée centrale de ce billet est que l'utilisation CPU ne prend comme indicateur que la « situation » où le CPU est occupé, et considère même le CPU comme busy lorsqu'il est en attente
    Et l'IPC est un indicateur qui permet de saisir la quantité réelle de travail utile cachée à l'intérieur de cet état busy

    • Je me demande pourquoi les gens qui s'appellent Brendan s'intéressent autant aux problèmes d'utilisation CPU
      S'il existe un autre Brendan, j'aimerais bien qu'on m'explique
  • Je ne pense pas qu'il faille compter les performances apportées par l'hyperthreading comme si elles doublaient
    Dans la réalité, même quand l'hyperthreading est bien exploité, il n'apporte souvent qu'environ 15 à 30 % de performance supplémentaire. En revanche, la latence peut doubler
    Il faut aussi absolument prendre en compte la baisse de fréquence quand l'utilisation des cœurs monte, donc il faut toujours garder en tête qu'en pratique tout cela est non linéaire
    Même avec les seules informations fournies par l'OS, si l'on tient compte de l'effet de l'hyperthreading et de la baisse de fréquence, on peut estimer l'utilisation de manière bien plus précise
    Au-delà de cela, je ne pense pas qu'il soit particulièrement difficile de modéliser aussi les cas où les limitations de cache ou de bande passante mémoire, ou encore les stalls du pipeline, conduisent à une baisse de performance

    • Ce qui complique encore la situation, c'est que l'efficacité de l'hyperthreading varie énormément selon l'architecture CPU et le workload
      Par exemple, les implémentations AMD (surtout les Zen récents) ont tendance à offrir des performances bien plus indépendantes que celles d'Intel, à supposer qu'il n'y ait pas de goulot d'étranglement côté bande passante mémoire

    • Pour des applications memory-bound, il est plus facile d'observer une meilleure montée en charge avec l'hyperthreading
      Sur un projet de moteur de rendu dont je m'étais occupé auparavant, comme il était memory-bound, l'hyperthreading à lui seul avait apporté un gain de performance de 60 à 70 %

    • Il y a longtemps, j'avais lancé un petit benchmark avec POV-Ray sur un i7-3770K (4C/8T)
      De 1 thread à 2 threads, c'était exactement le double, idem de 2 à 4, mais de 4 à 8 on ne gagnait qu'environ 15 %
      Avec un benchmark atypique qui répéterait artificiellement des cache misses, on pourrait peut-être tirer presque 2× de performance avec le SMT, mais je doute du réalisme d'un tel scénario
      PS : j'hésite à relancer le test POV-Ray. Ça fait tellement longtemps que ça me rend nostalgique

  • J'ai l'impression que l'auteur s'est rendu compte que les performances n'augmentent pas linéairement en fonction du % d'utilisation CPU, et qu'il en a conclu que le % d'utilisation CPU lui-même est un « mensonge »
    Même sans hyperthreading ni baisse de fréquence, et même dans des cas censés avoir peu de variables comme l'Apple Silicon, on n'obtient pas un scaling exactement proportionnel
    Dès qu'on commence à utiliser plusieurs cœurs en parallèle, des goulots d'étranglement sur des ressources autres que le CPU, comme le surcoût de transfert de données, deviennent fréquents, et on rencontre souvent des situations similaires

    • L'Apple Silicon aussi voit sa fréquence beaucoup baisser, surtout sur les modèles sans ventilateur (refroidissement passif)
  • La terminologie de l'auteur sur les cœurs est confuse et ne correspond pas au standard
    Il parle du 5900X comme d'un système à 24 cœurs, alors qu'en réalité il s'agit de 12 cœurs physiques avec 24 threads hyperthreadés
    Les 12 premiers sont les cœurs physiques, et les 12 autres sont les threads exécutés en association avec chacun de ces cœurs
    Même s'il y a deux jeux d'instruction pipeline, les unités fonctionnelles internes restent partagées

    • Il y a quelques années, en essayant d'expliquer l'hyperthreading à mon petit frère qui ne connaissait pas bien le sujet, j'avais trouvé une analogie qui m'est restée : c'est un peu comme un rouleau de papier toilette à deux plis
      On ne peut pas détacher indépendamment les 24, mais c'est un peu comme utiliser deux fois plus efficacement un ensemble de 12

    • Après les retours, j'ai corrigé la description en 12 cœurs / 24 threads
      Cela dit, comme mon OS affichait l'utilisation sur 24 cœurs, cela m'avait induit en erreur

    • Ce serait intéressant si Intel sortait des cœurs définis par logiciel
      L'inverse logique de l'hyperthreading : une structure où deux cœurs ou plus partageraient leurs ressources pour se transformer en « un gros cœur »
      Voir le brevet ci-dessous
      https://patents.google.com/patent/EP4579444A1/en

    • Si une paire SMT exécute des workloads du même type, l'effet SMT diminue à cause de la contention sur les ressources internes et les unités d'exécution
      Si les workloads sont totalement différents, le gain peut au contraire être plus important
      Désormais, avec en plus des variables comme les P-cores, E-cores, le turbo ou non-turbo sur les CPU récents, la situation devient encore plus complexe
      J'avais lu une étude indiquant que l'ajout de SMT apportait un meilleur gain de performance par watt que l'ajout de turbo, ce que j'avais trouvé très intéressant

  • Je trouve ça vraiment très parlant
    Un jour, autrefois, le CPU d'un serveur était monté à 60 %, et quand j'ai essayé d'expliquer à mon manager qu'il n'y avait déjà plus de marge, il m'a regardé avec un air bizarre
    J'aurais aimé avoir exactement ce genre d'explication à ce moment-là

    • Si on explique aussi la théorie des files d'attente, c'est imparable
      En dessous de 60 %, le délai de mise en file est pratiquement négligeable
      Vers 70 %, la latence commence à devenir très perceptible, et à partir de 80 % elle double presque
      Dans mon expérience, je visais 65 % sur le P95, et cela correspondait presque exactement au seuil théorique
      En pratique, la règle est donc : « 60 % comme limite d'usage, explosion de la latence à partir de 80 % »

    • Mais cela peut complètement varier selon le workload
      Surtout à notre époque où les CPU serveur ont 32 cœurs chacun

  • Il y a beaucoup de cas où l'utilisation CPU ne se comporte pas comme on s'y attend
    En général, avec ce genre d'article, je m'attendais à une discussion sur la manière dont les chiffres d'utilisation tournent sous Linux ou Windows, mais en réalité il y a aussi beaucoup de cas où le CPU reste tranquillement en attente ou downclocké à cause d'un goulot d'étranglement RAM
    En réalité, l'utilisation CPU ne fait que mesurer, côté OS (que ce soit Windows ou Linux), à quel point des threads sont affectés à chaque cœur
    Mais même si ce thread attend à 100 % dans memcpy, il est quand même compté dans l'utilisation
    L'avantage de l'hyperthreading, c'est que si un thread est bloqué sur l'unité AVX/vectorielle et qu'un autre est bloqué sur un simple memcpy/la RAM, on peut augmenter l'utilisation de chaque unité et améliorer au total les performances comme l'utilisation
    En fin de compte, la CPU Utilization reste depuis longtemps un sujet difficile à comprendre intuitivement, et de nouveaux angles d'analyse continuent d'apparaître
    Mais c'est toujours un sujet intéressant

  • Le vrai « mensonge », c'est de croire qu'un cœur hyperthreadé fonctionne exactement comme un vrai cœur
    À force d'utiliser cela depuis plus de 20 ans, on en oublie la nature d'origine, puis on redécouvre régulièrement pourquoi les chiffres de performance paraissent étranges
    Autre point : fondamentalement, un processeur est soit « en exécution » (100 %), soit « en attente » (0 %)
    Le simple fait de lui attribuer un pourcentage intermédiaire revient à rappeler qu'il ne s'agit que d'une moyenne sur une certaine unité de temps

  • J'ai déjà eu ce genre de conversation
    Manager : l'utilisation CPU est à 100 %, ne faudrait-il pas passer le serveur sur une instance plus grosse ?
    Moi : « Mais est-ce que le CPU fait vraiment un travail utile, là ? »
    Au final, le busy waiting est lui aussi compté dans l'utilisation CPU, donc parfois le chiffre monte sans rapport avec le travail réellement utile

 
jjjajh 2025-09-04

C'est exact.