{"id":20778,"date":"2026-08-18T18:23:16","date_gmt":"2026-08-18T16:23:16","guid":{"rendered":"https:\/\/webhosting.de\/linux-scheduler-latenz-messen-und-optimieren-performance\/"},"modified":"2026-08-18T18:23:16","modified_gmt":"2026-08-18T16:23:16","slug":"mesurer-la-latence-du-planificateur-linux-et-optimiser-les-performances","status":"publish","type":"post","link":"https:\/\/webhosting.de\/fr\/linux-scheduler-latenz-messen-und-optimieren-performance\/","title":{"rendered":"Mesurer et optimiser la latence du planificateur Linux pour am\u00e9liorer les performances du noyau"},"content":{"rendered":"<p>Je mesure la latence du <strong>Planificateur Linux<\/strong> de mani\u00e8re cibl\u00e9e, j'analyse les valeurs aberrantes et j'optimise les param\u00e8tres jusqu'\u00e0 ce que les charges de travail interactives et en temps r\u00e9el r\u00e9agissent de mani\u00e8re fiable. Je r\u00e9duis ainsi syst\u00e9matiquement la latence du planificateur et j'am\u00e9liore la <strong>Performances du noyau<\/strong> sans voler \u00e0 l'aveugle.<\/p>\n\n<h2>Points centraux<\/h2>\n\n<ul>\n  <li><strong>M\u00e9thodes de mesure<\/strong>: les commandes \u00ab perf sched \u00bb, \u00ab eBPF runqlat \u00bb, \u00ab schedstat \u00bb et \u00ab cyclictest \u00bb offrent une vue d'ensemble compl\u00e8te.<\/li>\n  <li><strong>Pire cas de figure<\/strong>: Les valeurs aberrantes dominent l'exp\u00e9rience utilisateur et les d\u00e9lais en temps r\u00e9el.<\/li>\n  <li><strong>Param\u00e8tres CFS<\/strong>: les param\u00e8tres `sched_latency_ns` et les tranches de temps d\u00e9terminent les temps de r\u00e9ponse.<\/li>\n  <li><strong>Politiques<\/strong>: Les politiques SCHED_FIFO, RR et DEADLINE accordent la priorit\u00e9 aux threads critiques.<\/li>\n  <li><strong>Isolation<\/strong>: Le \u00ab CPU-Pinning \u00bb et le r\u00e9glage des IRQ permettent de stabiliser les latences.<\/li>\n<\/ul>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/linux-performance-2349.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Ce que signifie la latence du planificateur dans le noyau<\/h2>\n\n<p>Je d\u00e9finis la latence du planificateur comme le temps \u00e9coul\u00e9 entre le <strong>R\u00e9veil<\/strong> d'une t\u00e2che et le moment o\u00f9 son code s'ex\u00e9cute apr\u00e8s le changement de contexte. Une interruption met fin \u00e0 une phase d\u2019attente d\u2019E\/S, le gestionnaire marque le thread comme pr\u00eat \u00e0 s\u2019ex\u00e9cuter, le planificateur effectue la s\u00e9lection et d\u00e9clenche le changement. Pour les syst\u00e8mes interactifs, chaque microseconde compte, mais au quotidien, c\u2019est surtout la <strong>Pire cas de figure<\/strong>-La latence affecte la perception. Quelques centaines de millisecondes suffisent \u00e0 g\u00e2cher l'exp\u00e9rience utilisateur, m\u00eame si la moyenne semble satisfaisante. C'est pr\u00e9cis\u00e9ment pour cette raison que j'examine l'ensemble de la cha\u00eene au niveau du noyau, tout en me concentrant sur la partie comprise entre le r\u00e9veil et l'entr\u00e9e dans le CPU.<\/p>\n\n<h2>Pourquoi la latence dans le pire des cas est importante<\/h2>\n\n<p>Je ne me base pas uniquement sur les moyennes, car une moyenne \u00e9lev\u00e9e peut cacher <strong>Pointes<\/strong> peut masquer. Le son gr\u00e9sille lorsque de rares pics vident les tampons, et les op\u00e9rations boursi\u00e8res perdent leur synchronisation lorsque les d\u00e9lais sont d\u00e9pass\u00e9s. Que ce soit pour les ordinateurs de bureau, les serveurs ou le temps r\u00e9el, la r\u00e8gle est la suivante : quelques valeurs aberrantes suffisent \u00e0 influencer la <strong>R\u00e9activit\u00e9<\/strong> plus efficace que des milliers de bons \u00e9chantillons. C'est pourquoi je vise des distributions \u00e9troites et des valeurs de gigue contr\u00f4l\u00e9es. Ce n'est que lorsque les valeurs maximales baissent qu'on obtient un d\u00e9roulement fluide et pr\u00e9visible.<\/p>\n\n<h2>Mesurer la latence du planificateur : outils et proc\u00e9dure<\/h2>\n\n<p>Je commence avec <strong>parfait<\/strong> et j\u2019enregistre les \u00e9v\u00e9nements du planificateur en fonction de la charge de travail : \u201e perf sched record \u201c collecte les donn\u00e9es, \u201e perf sched latency \u201c les classe par t\u00e2che, \u201e perf sched timehist \u201c affiche les \u00e9v\u00e9nements avec des horodatages. Je peux ainsi visualiser le temps d\u2019attente entre le \u201e sched-out \u201c et le \u201e sched-in \u201c, le d\u00e9lai entre le r\u00e9veil et l\u2019ex\u00e9cution effective, ainsi que la dur\u00e9e d\u2019ex\u00e9cution pure. Pour une analyse d\u00e9taill\u00e9e du CPU, je combine cela avec ce guide : <a href=\"https:\/\/webhosting.de\/fr\/linux-perf-outil-analyse-des-goulots-detranglement-du-processeur-optimisation-charge-du-serveur-profilage\/\">perf pour les goulots d'\u00e9tranglement du processeur<\/a>. Cette perspective permet de mettre en \u00e9vidence les goulots d'\u00e9tranglement et de d\u00e9terminer si ceux-ci sont dus \u00e0 des conflits d'acc\u00e8s, \u00e0 des priorit\u00e9s ou \u00e0 des surco\u00fbts.<\/p>\n\n<p>Avec eBPF, je mesure les temps d'attente d'ex\u00e9cution directement dans la <strong>Runqueue<\/strong>. La commande habituelle \u201e runqlat \u201c g\u00e9n\u00e8re des histogrammes par paliers de nanosecondes, ce qui me permet d\u2019identifier les zones typiques et les pics inhabituels. Ces distributions r\u00e9agissent de mani\u00e8re perceptible \u00e0 l\u2019isolation du processeur ou aux changements de politique, fournissant ainsi des preuves tangibles pour les \u00e9tapes de r\u00e9glage. Je r\u00e9p\u00e8te les mesures avant et apr\u00e8s les modifications jusqu\u2019\u00e0 ce que les pics disparaissent. Ce n\u2019est qu\u2019alors que je consid\u00e8re le r\u00e9sultat comme satisfaisant.<\/p>\n\n<p>Pour les t\u00e2ches individuelles, je me r\u00e9f\u00e8re \u00e0 \u201e \/proc\/\/schedstat \u201c et je compare les parts de temps d'ex\u00e9cution du processeur, <strong>Runqueue<\/strong>- Temps d'attente et phases de veille. Les donn\u00e9es sont relev\u00e9es \u00e0 intervalles r\u00e9guliers, ce qui permet d'obtenir des indicateurs tels que le pourcentage d'utilisation du processeur, le pourcentage de latence et le pourcentage de temps de veille. Je peux ainsi rapidement d\u00e9terminer si le processus est en manque de temps processeur ou s'il est bloqu\u00e9 par des op\u00e9rations d'E\/S. Cette clart\u00e9 \u00e9vite les optimisations erron\u00e9es qui agissent sur les mauvais leviers. Comme test compl\u00e9mentaire, j\u2019utilise cyclictest avec une priorit\u00e9 \u00e9lev\u00e9e pour documenter la gigue et les valeurs maximales.<\/p>\n\n<h2>Lire et interpr\u00e9ter les mesures<\/h2>\n\n<p>Je commence par analyser les donn\u00e9es de mesure d'un point de vue qualitatif : o\u00f9 les temps d'attente sont-ils les plus fr\u00e9quents, et quels sont les threads qui reviennent r\u00e9guli\u00e8rement avec <strong>Peaks<\/strong> . Ensuite, je v\u00e9rifie s\u2019ils sont li\u00e9s \u00e0 des limites du processeur, \u00e0 des conflits de politiques ou \u00e0 des temp\u00eates d\u2019interruptions. Je r\u00e8gle la dur\u00e9e d\u2019\u00e9chantillonnage suffisamment longue pour capturer les \u00e9v\u00e9nements rares, mais suffisamment courte pour examiner les changements de mani\u00e8re isol\u00e9e. Des valeurs de l'ordre de la microseconde conviennent au quotidien, mais certaines charges de travail en temps r\u00e9el exigent parfois des plages encore plus \u00e9troites. L'essentiel reste de savoir si la latence maximale diminue de mani\u00e8re fiable et si la gigue s'amenuise.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/linuxscheduler_9374.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Param\u00e8tres du planificateur Linux qui influencent la latence<\/h2>\n\n<p>Je commence par ajuster la latence cible \u201e sched_latency_ns \u201c, qui d\u00e9finit la fen\u00eatre temporelle dans laquelle toutes les t\u00e2ches pr\u00eates \u00e0 s'ex\u00e9cuter <strong>CPU<\/strong>-Temps. Dans de nombreux processus, la tranche de temps allou\u00e9e \u00e0 chaque t\u00e2che diminue, tandis que dans quelques-uns, elle augmente, ce qui garantit l'\u00e9quit\u00e9 mais peut d\u00e9caler les temps de r\u00e9ponse. Pour les applications interactives, je r\u00e9duis mod\u00e9r\u00e9ment ce param\u00e8tre afin de favoriser des temps de r\u00e9ponse courts, tout en surveillant la surcharge. Le CFS r\u00e9partit les temps de mani\u00e8re \u00e9quitable, mais les charges de travail comportant des threads critiques b\u00e9n\u00e9ficient de priorit\u00e9s clairement d\u00e9finies. Je r\u00e9sume ici les principes fondamentaux de l\u2019ordonnancement \u00e9quitable dans le contexte de l\u2019h\u00e9bergement : <a href=\"https:\/\/webhosting.de\/fr\/cfs-scheduler-planification-equitable-hebergement\/\">Comprendre le planificateur CFS<\/a>.<\/p>\n\n<p>Outre la latence et les quanta, la granularit\u00e9 de r\u00e9veil et la logique de migration ont une incidence sur <strong>Pointes<\/strong>. Des migrations trop agressives nuisent \u00e0 la localit\u00e9 du cache et allongent indirectement les temps d'attente. Je r\u00e9duis les d\u00e9placements inutiles, je fixe les threads actifs et je conserve les donn\u00e9es \u00e0 proximit\u00e9 de leurs c\u0153urs. Dans les environnements NUMA, cela s\u2019applique d\u2019autant plus que les distances de m\u00e9moire augmentent les latences. L\u2019objectif reste un environnement de planification stable et pr\u00e9visible.<\/p>\n\n<h2>Utiliser judicieusement les politiques, les priorit\u00e9s et les \u00e9ch\u00e9ances<\/h2>\n\n<p>J'attribue aux fils de discussion critiques <strong>SCHED_FIFO<\/strong> ou la priorit\u00e9 SCHED_RR, lorsque la latence prime sur le d\u00e9bit. Avec SCHED_DEADLINE, je peux allouer des ressources avec pr\u00e9cision en fonction des p\u00e9riodes, de la dur\u00e9e d'ex\u00e9cution et des d\u00e9lais, ce qui permet de respecter les \u00e9ch\u00e9ances strictes. J'utilise ces politiques avec parcimonie afin que le syst\u00e8me ne manque pas de ressources. Je calibre les priorit\u00e9s jusqu\u2019\u00e0 ce que seuls les chemins vraiment essentiels soient autoris\u00e9s \u00e0 passer. Vous trouverez ici une introduction pratique aux priorit\u00e9s : <a href=\"https:\/\/webhosting.de\/fr\/server-process-scheduling-priorities-optimisation-serverboost\/\">Priorit\u00e9s en mati\u00e8re de proc\u00e9dures<\/a>.<\/p>\n\n<p>Je v\u00e9rifie r\u00e9guli\u00e8rement s'il y a des conflits entre les politiques, par exemple lorsque des t\u00e2ches en arri\u00e8re-plan consomment davantage <strong>Prio<\/strong> sous forme de threads d'interaction. Les param\u00e8tres de d\u00e9lai doivent \u00e9galement \u00eatre correctement dimensionn\u00e9s, sous peine de cr\u00e9er de nouveaux goulots d'\u00e9tranglement. Des tests avec des charges de travail r\u00e9elles permettent de valider ce choix. Je documente chaque modification et effectue des mesures de suivi afin que les effets restent tra\u00e7ables. J'\u00e9vite ainsi les effets ind\u00e9sirables en production.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/LinuxSchedulerOptimierung4321.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Isolation des processeurs, \u00ab pinning \u00bb et NUMA : stabiliser les latences<\/h2>\n\n<p>Je s\u00e9pare les threads critiques de la charge g\u00e9n\u00e9rale en isolant des processeurs d\u00e9di\u00e9s et en \u00e9cartant les services syst\u00e8me, l\u00e0 o\u00f9 une faible <strong>Latence<\/strong> est n\u00e9cessaire. Le \u00ab CPU pinning \u00bb maintient les \u00ab hot paths \u00bb sur des c\u0153urs fixes et pr\u00e9serve la localit\u00e9 du cache. Dans les configurations NUMA, j'associe les threads \u00e0 des banques de m\u00e9moire locales afin d'\u00e9viter les acc\u00e8s inutiles entre n\u0153uds. Ces mesures r\u00e9duisent sensiblement les effets de jitter. Le gain se traduit imm\u00e9diatement par des histogrammes eBPF plus serr\u00e9s.<\/p>\n\n<p>La r\u00e9partition des IRQ en fait partie : je d\u00e9tourne les interruptions g\u00eanantes des c\u0153urs \u00e0 latence \u00e9lev\u00e9e, ce qui permet de les soulager <strong>Hot<\/strong>-Threads. MSI-X et les affinit\u00e9s permettent de contr\u00f4ler avec pr\u00e9cision la r\u00e9partition. Dans la mesure du possible, j'utilise des IRQ multithread afin que le traitement des ISR soit plus rapide. Tout cela lib\u00e8re des ressources pour l'ex\u00e9cution des t\u00e2ches urgentes. Des mesures effectu\u00e9es avec perf et cyclictest confirment cet effet.<\/p>\n\n<h2>Optimisation des interruptions, des pilotes et de la pr\u00e9emption<\/h2>\n\n<p>Je d\u00e9place les parties n\u00e9cessitant des calculs intensifs de l'ISR vers des files d'attente de travail en aval, afin que le planificateur soit plus rapide <strong>changer de mode<\/strong> Je d\u00e9compose les sections critiques longues du noyau afin de cr\u00e9er davantage de points de pr\u00e9emption. Je d\u00e9sactive les fonctionnalit\u00e9s inutiles du noyau et les pilotes lourds lorsqu'ils augmentent les latences. Pour les applications en temps r\u00e9el strict, j\u2019utilise PREEMPT_RT ; pour une charge serveur importante, PREEMPT suffit souvent avec une bonne configuration. Il est important de mesurer pr\u00e9cis\u00e9ment chaque r\u00e9glage, plut\u00f4t que de se fier \u00e0 des hypoth\u00e8ses.<\/p>\n\n<p>Je v\u00e9rifie si les r\u00e9solutions de la minuterie et les options de tick sont adapt\u00e9es \u00e0 la charge de travail, car des ticks trop grossiers <strong>Jitter<\/strong> peuvent les accentuer. \u00c0 cela s'ajoute la gestion de l'\u00e9nergie : les \u00e9tats C profonds allongent les temps de r\u00e9veil et peuvent entra\u00eener des pics de latence. Gr\u00e2ce \u00e0 des r\u00e9glages optimis\u00e9s du r\u00e9gulateur, je parviens \u00e0 trouver un compromis viable. Au final, c\u2019est la coh\u00e9rence des valeurs mesur\u00e9es qui compte, et non le nom d\u2019une option. Une approche stable l\u2019emporte sur un r\u00e9glage ponctuel agressif.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/linux_scheduler_performance1234.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>\u00c9tapes de r\u00e9glage pratiques avec des exemples de valeurs<\/h2>\n\n<p>Je commence par effectuer une mesure de r\u00e9f\u00e9rence et je ne modifie qu'un seul <strong>Param\u00e8tres<\/strong> \u00e0 chaque cycle, afin de d\u00e9terminer la causalit\u00e9. Ensuite, je fais varier la valeur de `sched_latency_ns` par petits paliers, j\u2019observe les valeurs maximales et la gigue, et je consigne les effets observ\u00e9s. Si n\u00e9cessaire, je fixe les threads critiques et d\u00e9place les IRQ, je proc\u00e8de \u00e0 de nouvelles mesures et je note les pics. Lorsque les politiques le permettent, je passe de mani\u00e8re cibl\u00e9e en FIFO\/RR ou DEADLINE. Le tableau suivant r\u00e9pertorie les options courantes en fonction de leurs effets et de leurs effets secondaires :<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>Option\/M\u00e9canique<\/th>\n      <th>Impact pr\u00e9vu sur la latence<\/th>\n      <th>Effets secondaires possibles<\/th>\n      <th>Remarque<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td><strong>sched_latency_ns<\/strong> abaisser<\/td>\n      <td>Temps d'attente r\u00e9duit jusqu'\u00e0 l'acc\u00e8s au processeur<\/td>\n      <td>Une surcharge de planification plus importante<\/td>\n      <td>Petits pas, mesurer l'impact<\/td>\n    <\/tr>\n    <tr>\n      <td>R\u00e9gler la granularit\u00e9 du r\u00e9veil<\/td>\n      <td>Reprise plus rapide apr\u00e8s la sortie de veille<\/td>\n      <td>Pr\u00e9emptions plus fr\u00e9quentes<\/td>\n      <td>Ne r\u00e9glez que mod\u00e9r\u00e9ment<\/td>\n    <\/tr>\n    <tr>\n      <td>Fixation\/isolation du processeur<\/td>\n      <td>Plus stables <strong>Peaks<\/strong> et moins de gigue<\/td>\n      <td>Moins de flexibilit\u00e9<\/td>\n      <td>Prendre en compte les affinit\u00e9s IRQ<\/td>\n    <\/tr>\n    <tr>\n      <td>SCHED_FIFO\/RR<\/td>\n      <td>Mod\u00e8le pr\u00e9f\u00e9r\u00e9<\/td>\n      <td>Suppression d'autres t\u00e2ches<\/td>\n      <td>Uniquement pour les chemins critiques<\/td>\n    <\/tr>\n    <tr>\n      <td>PREEMPT_RT<\/td>\n      <td>Faible latence dans le pire des cas<\/td>\n      <td>Davantage de changements de contexte<\/td>\n      <td>Pilotes compatibles RT requis<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n<p>Je valide les modifications \u00e0 l'aide de \u00ab perf timehist \u00bb et d'histogrammes eBPF jusqu'\u00e0 ce que la <strong>Distribution<\/strong> \u00e9troite et que la valeur maximale reste prudente. En cas d'effets contradictoires, je fais un pas en arri\u00e8re et j'essaie une autre combinaison. Chaque environnement r\u00e9agit un peu diff\u00e9remment, c'est pourquoi il est important de proc\u00e9der \u00e0 des exp\u00e9rimentations rigoureuses. Gr\u00e2ce \u00e0 des benchmarks coh\u00e9rents, je d\u00e9montre objectivement l'int\u00e9r\u00eat de cette approche. C'est ainsi que na\u00eet un processus d'optimisation reproductible.<\/p>\n\n<h2>Contexte de l'h\u00e9bergement et des serveurs : r\u00e9duire efficacement la latence<\/h2>\n\n<p>Dans le domaine de l'h\u00e9bergement, un r\u00e9glage pr\u00e9cis du planificateur permet de r\u00e9duire les temps de r\u00e9ponse pour les sites Web et <strong>DB<\/strong>-Requ\u00eates. De nombreux processus simultan\u00e9s tirent profit de la r\u00e9duction des temps d\u2019attente dans la file d\u2019attente d\u2019ex\u00e9cution et de la suppression des pics de charge. Les piles de conteneurs et de microservices gagnent en r\u00e9gularit\u00e9 d\u00e8s lors que les services critiques se voient accorder la priorit\u00e9 et une proximit\u00e9 avec le processeur. Lors du choix d\u2019un fournisseur, il convient de veiller \u00e0 ce que le noyau soit \u00e0 jour, que la pr\u00e9emption soit judicieuse et que le contr\u00f4le des IRQ et du processeur soit flexible. Une latence r\u00e9duite a un impact direct sur le chiffre d\u2019affaires et l\u2019exp\u00e9rience utilisateur.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/08\/linux-performance-optimierung-4523.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Fonctionnalit\u00e9s modernes du noyau qui influencent la latence<\/h2>\n\n<p>Les noyaux actuels int\u00e8grent des m\u00e9canismes qui influencent directement les temps de r\u00e9ponse. Dans ses versions r\u00e9centes, le CFS b\u00e9n\u00e9ficie d\u2019heuristiques affin\u00e9es pour les r\u00e9veils et les \u00e9victions, qui privil\u00e9gient les charges interactives. Des attributs tels que <strong>Pr\u00e9f\u00e9rence en mati\u00e8re de veille et de latence<\/strong> par thread, cela permet d'acc\u00e9l\u00e9rer le traitement des chemins importants sans abuser des politiques RT. De plus, cela permet de contr\u00f4ler <strong>uclamp<\/strong> (limitation d'utilisation) : l'utilisation minimale et maximale du processeur, telle que d\u00e9finie par le planificateur, pour chaque t\u00e2che ou cgroup. Cela me permet d'imposer une limite inf\u00e9rieure de puissance de calcul aux threads pour lesquels la latence est critique, ce qui influence le r\u00e9gulateur de fr\u00e9quence et l'affectation aux c\u0153urs actifs.<\/p>\n\n<p>Pour les syst\u00e8mes \u00e0 faible fr\u00e9quence de tick, j'utilise <strong>NOHZ_FULL<\/strong> en combinaison avec des processeurs d\u00e9di\u00e9s \u00e0 la gestion interne. Cela permet de d\u00e9charger les c\u0153urs sensibles \u00e0 la latence des t\u00e2ches p\u00e9riodiques du noyau. De plus, j\u2019all\u00e8ge la charge de ces c\u0153urs via <code>rcu_nocbs<\/code>, afin que les callbacks ne les d\u00e9stabilisent pas. Ces deux mesures r\u00e9duisent les pr\u00e9emptions inopportunes et stabilisent les valeurs dans le pire des cas.<\/p>\n\n<p>Avec <strong>PSI<\/strong> (Pressure Stall Information) : je mesure la pression du syst\u00e8me au niveau du processeur, de la m\u00e9moire et des E\/S. Les indicateurs dans <code>\/proc\/pressure\/*<\/code> indiquent si des threads sont bloqu\u00e9s en raison d'un manque de ressources. Si le CPU-PSI augmente parall\u00e8lement aux temps d'attente de la file d'attente d'ex\u00e9cution, cela indique clairement une v\u00e9ritable surcharge ou un contr\u00f4le des quotas trop strict.<\/p>\n\n<h2>Cgroups, conteneurs et \u00e9quit\u00e9 : une isolation sans surco\u00fbt<\/h2>\n\n<p>Dans les environnements de conteneurs, les Cgroups constituent le levier permettant de contr\u00f4ler la latence. J'utilise <strong>cpu.weight<\/strong>, afin de garantir une certaine \u00e9quit\u00e9, et j'utilise <strong>cpu.max<\/strong>, afin de limiter strictement les services d'arri\u00e8re-plan g\u00eanants. Les services critiques ne se voient pas attribuer un quota CPU restreint, afin qu'ils ne <em>r\u00e9gler le d\u00e9bit<\/em> et \u00eatre d\u00e9coup\u00e9es dans le temps. Pour garantir la proximit\u00e9 avec le processeur, je s\u00e9pare les cpusets : un ensemble de c\u0153urs pour les interactions, un autre pour le traitement par lots. Cette isolation est plus efficace qu\u2019un simple r\u00e9glage du niveau de priorit\u00e9 \u00ab nice \u00bb.<\/p>\n\n<p>Sur les plateformes avec orchestration, j\u2019\u00e9vite que plusieurs pods sensibles \u00e0 la latence partagent le m\u00eame c\u0153ur physique. Je r\u00e9serve des c\u0153urs <em>en exclusivit\u00e9<\/em> et je lie les IRQ correspondantes de mani\u00e8re coh\u00e9rente. Je mesure les modifications dans la hi\u00e9rarchie des cgroups \u00e0 l'aide d'eBPF via des filtres cgroup, afin de visualiser les temps d'attente dans la file d'attente d'ex\u00e9cution pour chaque service. Cela me permet de d\u00e9terminer si la r\u00e9partition de la charge ou les quotas sont la cause r\u00e9elle des pics.<\/p>\n\n<h2>Virtualisation et SMT : d\u00e9tection et att\u00e9nuation du bruit de l'h\u00f4te<\/h2>\n\n<p>Dans les machines virtuelles, je fais attention \u00e0 <strong>Voler du temps<\/strong>: Elle indique \u00e0 quel moment l'hyperviseur soustrait du temps CPU au syst\u00e8me invit\u00e9. Si perf affiche de bons chemins, mais que l'application est saccad\u00e9e, c'est souvent le \u00ab Steal Time \u00bb qui en est la cause. Pour y rem\u00e9dier, <em>Affectation des vCPU<\/em> sur des pCPU d\u00e9di\u00e9s, des taux de surallocation r\u00e9duits et la s\u00e9paration des threads d'E\/S sur des c\u0153urs distincts. Pour une latence constante, je pr\u00e9vois pCPU = vCPU ; sinon, le cas le plus d\u00e9favorable est pratiquement impossible \u00e0 calculer.<\/p>\n\n<p>Avec <strong>SMT<\/strong> (Hyper-Threading), je partage les ressources du c\u0153ur avec un c\u0153ur \u00ab fr\u00e8re \u00bb. Je redirige donc les chemins de latence vers des c\u0153urs dont les c\u0153urs \u00ab fr\u00e8res \u00bb sont libres, ou j'utilise des options de planification des c\u0153urs qui limitent les interf\u00e9rences entre les c\u0153urs. Lorsque les objectifs sont tr\u00e8s exigeants, je d\u00e9sactive le SMT de mani\u00e8re s\u00e9lective pour les c\u0153urs critiques. Le gain provient d\u2019une concurrence moindre au niveau des ports, des caches et des unit\u00e9s d\u2019ex\u00e9cution.<\/p>\n\n<h2>Chemins d'acc\u00e8s au stockage, aux E\/S et au r\u00e9seau : des sources de latence cach\u00e9es<\/h2>\n\n<p>La latence du planificateur donne souvent l'impression d'\u00eatre un probl\u00e8me li\u00e9 au processeur, mais en r\u00e9alit\u00e9, c'est <strong>Reclaim<\/strong> ou <strong>Compaction<\/strong>. La r\u00e9cup\u00e9ration directe arr\u00eate les threads et g\u00e9n\u00e8re de longs pics. Je maintiens des pools de pages libres suffisamment \u00e9lev\u00e9s et je choisis une valeur mod\u00e9r\u00e9e <code>vm.swappiness<\/code>, afin que les acc\u00e8s \u00e0 la m\u00e9moire ne soient pas perturb\u00e9s par des op\u00e9rations de swap intenses. Je configure les \u00ab Transparent Huge Pages \u00bb de mani\u00e8re prudente : si le noyau regroupe les grandes pages \u00e0 un moment inopportun, cela entra\u00eene des ralentissements ; avec <em>madvise<\/em> Je place les THP l\u00e0 o\u00f9 ils permettent d'augmenter le d\u00e9bit sans perturber les interactions.<\/p>\n\n<p>Les intervalles de r\u00e9\u00e9criture et de validation du journal influencent \u00e9galement les interactions. Des limites de donn\u00e9es sales trop \u00e9lev\u00e9es repoussent le travail vers des phases d\u00e9favorables ; des limites trop basses entra\u00eenent des pics de vidage fr\u00e9quents. Je dimensionne en octets plut\u00f4t qu'en pourcentage et j'\u00e9tale les \u00e9critures afin que les phases d'\u00e9veil du processeur n'entrent pas en conflit avec les pics d'E\/S.<\/p>\n\n<p>Dans le chemin d'acc\u00e8s r\u00e9seau, je consulte <strong>SoftIRQs<\/strong>, les budgets NAPI et le regroupement de paquets. Un GRO trop agressif r\u00e9duit la surcharge par paquet, mais peut allonger la latence interactive. Les modes RPS\/RFS r\u00e9partissent bien la charge, mais doivent \u00eatre adapt\u00e9s aux affinit\u00e9s IRQ et CPU. L\u2019objectif est que les paquets soient trait\u00e9s l\u00e0 o\u00f9 s\u2019ex\u00e9cute le thread de l\u2019application \u2013 et non pas qu\u2019ils doivent d\u2019abord transiter par plusieurs c\u0153urs.<\/p>\n\n<h2>\u00c9quilibrer la limitation du RT, les d\u00e9lais et les m\u00e9canismes de protection<\/h2>\n\n<p>Le <strong>Limitation du d\u00e9bit RT<\/strong> Cela prot\u00e8ge le syst\u00e8me contre la \u00ab famine \u00bb, mais limite efficacement la charge RT \u00e0 une partie du temps CPU. Pour obtenir des temps de r\u00e9ponse d\u00e9terministes, j'augmente <code>kernel.sched_rt_runtime_us<\/code> ou d\u00e9sactivez cette limite dans des environnements soigneusement isol\u00e9s. Je v\u00e9rifie alors syst\u00e9matiquement si les threads non-RT re\u00e7oivent encore suffisamment de fen\u00eatres. Les variables globales sont tout aussi importantes <strong>Date limite<\/strong>-Contingents : s'ils sont d\u00e9finis de mani\u00e8re trop restrictive, les t\u00e2ches DEADLINE ne respectent pas leurs cr\u00e9neaux horaires malgr\u00e9 des param\u00e8tres corrects. Je v\u00e9rifie le rapport entre <em>dur\u00e9e d'ex\u00e9cution<\/em> \u00e0 <em>p\u00e9riode<\/em> et la somme de toutes les r\u00e9servations DEADLINE par CPU.<\/p>\n\n<h2>Conception des mesures, protection contre la r\u00e9gression et exploitation<\/h2>\n\n<p>Je s\u00e9pare strictement les phases de mesure : pr\u00e9chauffage, r\u00e9f\u00e9rence, variation, v\u00e9rification. Les caches \u00ab froids \u00bb faussent les r\u00e9sultats ; je mesure les phases stabilis\u00e9es et je les corr\u00e8le avec les donn\u00e9es Perf et eBPF. Les comparaisons A\/B sont effectu\u00e9es avec des charges de travail identiques, une dur\u00e9e identique et des affinit\u00e9s fixes. Je choisis des fen\u00eatres d'\u00e9chantillonnage suffisamment grandes pour que les pics rares apparaissent statistiquement, mais suffisamment petites pour \u00e9valuer isol\u00e9ment chaque \u00e9tape de r\u00e9glage.<\/p>\n\n<p>Pour un fonctionnement en continu, je d\u00e9finis une <strong>SLO<\/strong> pour la latence et la gigue : environ le quantile 99,9% inf\u00e9rieur \u00e0 X microsecondes sous une charge Y. La t\u00e9l\u00e9m\u00e9trie issue de PSI, des statistiques de performance et des histogrammes eBPF sert de syst\u00e8me de surveillance ; si les indicateurs d\u00e9passent les seuils, je bascule automatiquement vers des profils conservateurs. Chaque modification fait l\u2019objet d\u2019un journal des modifications comprenant la version du noyau, les param\u00e8tres, les m\u00e9thodes de mesure, les donn\u00e9es brutes et leur interpr\u00e9tation. Ainsi, le r\u00e9glage reste reproductible \u2013 et il est possible de revenir en arri\u00e8re \u00e0 tout moment.<\/p>\n\n<ul>\n  <li>Cr\u00e9er une base de r\u00e9f\u00e9rence : perf, eBPF, schedstat, cyclictest<\/li>\n  <li>Identifier le goulot d'\u00e9tranglement : CPU, IRQ, E\/S, m\u00e9moire, politique<\/li>\n  <li>Une modification par cycle : param\u00e8tres, \u00e9pinglage, politique, isolation<\/li>\n  <li>Mesure avant\/apr\u00e8s : moyenne, quantiles 99% et 99,9%, maximum<\/li>\n  <li>Tester la stabilit\u00e9 : ex\u00e9cutions prolong\u00e9es, charges de travail r\u00e9elles, pics de charge<\/li>\n  <li>Documenter et conserver : profils, valeurs limites, plan d'intervention en cas de r\u00e9cidive<\/li>\n<\/ul>\n\n<h2>En bref<\/h2>\n\n<p>Je mesure la latence du planificateur avec <strong>parfait<\/strong>, eBPF, schedstat et cyclictest, avant de toucher \u00e0 quoi que ce soit. Ensuite, je r\u00e9duis progressivement la latence cible, je calibre les politiques et je prot\u00e8ge les threads critiques \u00e0 l'aide du pinning et des affinit\u00e9s d'IRQ. Je d\u00e9finis les pilotes, la r\u00e9partition des ISR et la pr\u00e9emption de mani\u00e8re \u00e0 faire baisser les pics dans le pire des cas et \u00e0 r\u00e9duire la gigue. Je valide chaque modification par des mesures r\u00e9p\u00e9t\u00e9es jusqu\u2019\u00e0 ce que les courbes soient convaincantes. C\u2019est ainsi que j\u2019augmente la <strong>Noyau<\/strong>- offre une r\u00e9activit\u00e9 durable et fournit des r\u00e9sultats fiables pour les postes de travail, les serveurs et les charges de travail en temps r\u00e9el.<\/p>","protected":false},"excerpt":{"rendered":"<p>Guide pratique pour mesurer et optimiser la latence du planificateur Linux afin d'am\u00e9liorer les performances du noyau. Th\u00e8me principal : la latence du planificateur sous Linux pour une planification pr\u00e9cise de l'utilisation du processeur et des temps de r\u00e9ponse stables des serveurs.<\/p>","protected":false},"author":1,"featured_media":20771,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[676],"tags":[],"class_list":["post-20778","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server_vm"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"181","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"Linux Scheduler","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"20771","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/posts\/20778","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/comments?post=20778"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/posts\/20778\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/media\/20771"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/media?parent=20778"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/categories?post=20778"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/fr\/wp-json\/wp\/v2\/tags?post=20778"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}