P-states і C-states: що робить ваш CPU у простої

Було корисно?

Звіт про інцидент завжди починається однаково: «CPU був лише на 12% і затримка все одно підскочила.»
Ви дивитесь панелі моніторингу, бачите багато запасу, і хтось пропонує «можливо база даних гальмує».
Тим часом справжній винуватець тихіший: процесор енергонезбережно заощаджує настільки агресивно, що його пробудження коштує вам мілісекунди, яких ви не закладали.

P-states і C-states — це ручки і шестерні за поняттям «простій». Вони також причина того, чому сервер може бути «переважно в простій»
і при цьому відчуватися так, ніби ми йдемо крізь мед, коли приходить черговий сплеск роботи. Якщо ви керуєте продакшеном,
вам не потрібно ставати мікроархітектором CPU — але потрібно мати достатню операційну грамотність, щоб не наступити на міни.

Продукційна ментальна модель: P-states vs C-states

Уявіть свій CPU як пристрій, що має два типи «режимів»:

  • P-states (Performance states): процесор виконує інструкції, але на різних точках частоти/напруги.
    Вищий P-state зазвичай означає вищу частоту і більше споживання. Нижчий P-state — повільніше, але економніше.
  • C-states (Idle states): процесор не виконує корисних інструкцій.
    Чим глибший C-state, тим більша частина ядра (а іноді й усього пакета) може бути вимкнена живленням, що економить енергію — але пробудження займає більше часу.

Це проста версія. Операційна версія додає два зауваження, які варто викарбувати у ваших рунах:

  • P-states не є «поставив і забув». ОС, прошивка та сам процесор можуть впливати на вибір частоти.
    У сучасних системах Intel апарат може приймати багато рішень навіть якщо ви вважаєте, що Linux керує.
  • C-states можуть бути як для окремого ядра, так і для пакета. Одне галасливе сусіднє ядро може не дозволити всьому сокету перейти в глибокий пакетний сон.
    Навпаки, «тиха» система може зайти так глибоко в сон, що наступний запит заплатить неприємний штраф за пробудження.

Ще один ментальний ярлик: P-states — про «наскільки швидко під час роботи». C-states — про «наскільки сплячий під час очікування».
Більшість інцидентів трапляється, коли ви оптимізуєте одне й забуваєте про інше.

Що фактично спрацьовує, коли CPU «в просте»

Коли в Linux немає нічого runnable для CPU, він виконує цикл idle. Цикл простою — це не просто спінінг
(якщо ви не змусите його). Зазвичай він видає інструкцію на кшталт HLT або використовує більш просунуті
механізми, що дозволяють процесору входити в глибші стани сну.

Core C-states: від C0 до «достатньо глибоко, щоб нервувати»

C0 означає «активний». Усі інші — якісь варіації «не виконуються інструкції». Точне відповідність відрізняється між вендорами,
але операційна модель послідовна:

  • C1: легкий сон. Швидке виходження. Мінімальна економія енергії.
  • C1E: покращений C1; часто агресивніше знижує напругу.
  • C3: глибший сон; вимикаються внутрішні тактові сигнали; більша латентність виходу.
  • C6/C7 та інші: дуже глибокий сон; можуть скидати кеші, вимикати частини ядра; латентність виходу може стати відчутною.

Латентність виходу — прихований податок. Якщо ваше навантаження сплескове і чутливе до затримки, глибокі C-states можуть перетворити
«переважно в просте» на «періодично повільно».

Package C-states: весь сокет дрімає

Пакетні C-states (часто позначаються як PC2/PC3/PC6/PC10) — де живуть великі енергозбереження.
Там же й несподіванки. Пакет може перейти в глибокий сон лише якщо виконані умови:

  • Всі ядра достатньо простоюють.
  • Uncore-компоненти (LLC, контролер пам’яті, інтерконект) можуть бути відключені/вимкнені.
  • Пристрої та прошивка погоджуються, що це безпечно.

У серверних середовищах один галасливий джерело переривань, таймерний сплеск або неправильно налаштована політика енергозбереження може блокувати глибокі пакетні стани.
Або навпаки: дозволено глибокий пакетний сон, і ваша хвостова затримка починає танцювати інтерпретаційний танець.

P-states: вибір частоти вже не один регулятор

Стара історія була така: ОС вибирає частоту з таблиці; CPU її виконує. Сучасна історія: ОС встановлює політики і підказки,
а внутрішня логіка CPU часто виконує швидкі контурні регулювання. Драйвер intel_pstate від Intel, CPPC від AMD
і апаратно керовані P-states розмивають межу між «governor» і «прошивкою».

Турбо ускладнює ситуацію ще більше. Турбо — це не «одна частота». Це набір опортуністичних поведінкових підвищень частоти,
обмежених потужністю, температурою, струмом та кількістю активних ядер. Ваш моніторинг може писати «3.5 GHz»,
тоді як процесор виконує підвищення на кожному ядрі, що змінюються мікросекунда за мікросекунду.

Жарт №1: Якщо хочете відчути себе безсилим, спробуйте посперечатися з CPU про те, що таке «максимальна частота».

Чому це важливо: затримки, джиттер, пропускна здатність і витрати

Затримка і хвостова затримка

Глибокі C-states додають латентність пробудження. Масштабування частоти додає латентність підйому. Зазвичай це мікросекунди до низьких мілісекунд,
що звучить мало, поки ви не працюєте з:

  • RPC-сервісами з жорсткими SLO (важливий p99, а не середнє)
  • бекендами зберігання, де час завершення IO видно користувачу
  • базами даних з блокуванням, де малі затримки масштабуються
  • системами низької затримки трейдингу, де джиттер — ризик для кар’єри

Іншими словами: якщо ваша система «переважно проста», але має швидко відповідати під час активності, це треба контролювати.

Пропускна здатність і стійка продуктивність

P-states і турбо вирішують, скільки роботи ви виконуєте на ват. Але турбо обмежене межами потужності (PL1/PL2 на Intel),
тепловими умовами та платформними обмеженнями. Якщо ви примусово увімкнете «режим продуктивності» всюди, ви можете виграти короткі бенчмарки, але програти в стійкій пропускній здатності,
коли досягнете меж потужності/тепла і почнеться жорстке троттлінг.

Енергія, охолодження і реальні гроші

Якщо ви оперуєте в масштабі, політика живлення CPU змінює історію дата-центру: електрика, охолодження і щільність стійок.
Навіть якщо ви безпосередньо не платите за електрику, ви відчуєте це в плануванні ємності.

Цинічна SRE-істина: ви не зможете купити собі вихід із джитеру затримки, якщо конфігурація флоту неконсистентна.
І ви не зможете налаштуваннями вирішити обмеження бюджету потужності, якщо ваш додаток спінить, нічого не роблячи.

Цікаві факти та коротка історія (бо цей безлад має корені)

  • ACPI стандартизував стани живлення, щоб ОС могли керувати енергоспоживанням між різними вендорами замість унікальних BIOS-інтерфейсів.
  • Ранні ери SpeedStep зробили масштабування частоти загальнодоступним; до того «енергоменеджмент» був переважно «вимкнути екран».
  • Сучасна турбо-поведінка обмежена потужністю, а не частотою: процесори намагаються триматися в межах енергетичних і теплових конвертів, а не за фіксованим тактом.
  • C-states існували до хмари, але хмара зробила їхні компроміси болючими: multi-tenant навантаження сплескові й непередбачувані.
  • Tickless ядра (NO_HZ) зменшили періодичні таймерні переривання, щоб CPU могли довше бути в простій і досягати глибших C-states.
  • Intel ввів апаратне управління P-states, щоб реагувати швидше, ніж цикл планувальника ОС.
  • RAPL (Running Average Power Limit) дав софту спосіб вимірювати/обмежувати енергію CPU, зробивши енергію першокласною метрикою.
  • Пакетні C-states стали важливими, коли «uncore» енергія (LLC, контролер пам’яті, інтерконект) почала конкурувати з енергією ядра.
  • Віртуалізація усе ускладнила: «простой» в гості не означає простій на хості; зупинка в VM передбачає політику гіпервізора.

Як Linux керує P-states і C-states

The control plane: drivers, governors, and policies

У Linux масштабування частоти CPU зазвичай керує підсистема cpufreq. Два поширені драйвери:

  • intel_pstate (Intel): часто за замовчуванням на сучасних Intel. Може працювати в «active» режимі, де CPU сильно бере участь у рішеннях.
  • acpi-cpufreq: більш традиційний ACPI-драйвер з явними таблицями частот.

Governor-и — політики на кшталт performance, powersave і (залежно від драйвера) schedutil.
Не сприймайте назви governor-ів як універсальні істини; їхня поведінка може відрізнятися в залежності від драйвера.

The idle plane: cpuidle, C-state drivers, and latency constraints

C-states у Linux керуються підсистемою cpuidle. Вона обирає стан простою на основі:

  • очікуваної тривалості простою (як довго до наступної події, що розбудить CPU)
  • латентності виходу з кожного стану
  • QoS-обмежень (підказки про чутливість до латентності від ядра/користувацького простору)
  • чого дозволяє платформа і прошивка

BIOS/UEFI: the place where “we’ll just change one setting” becomes folklore

Налаштування прошивки можуть перевизначити або обмежити все:

  • Максимально дозволений C-state (наприклад, лімітувати до C1)
  • Обмеження пакетних C-state
  • Увімкнення/вимкнення турбо
  • Energy/Performance Bias (Intel’s EPB)
  • «Профілі енергії» вендора, що роблять кілька речей одночасно

У продакшені найпоширеніший збій — не «неправильний ядро». Це «різні BIOS за замовчуванням у різних партіях».

One reliability quote (paraphrased idea)

Парафраз ідеї, приписаної John Ousterhout: складність — корінь багатьох проблем надійності.
Енергоменеджмент — це складність із ватметром.

Практичні завдання: команди, значення виводу і рішення

Єдине налаштування, яке має значення — те, яке ви можете перевірити. Нижче реальні завдання, які я очікую від on-call інженера,
з командами, прикладами виводу і тим, яке рішення з них випливає.

Task 1: Identify the active CPU frequency driver and governors

cr0x@server:~$ cpupower frequency-info
analyzing CPU 0:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 0
  available cpufreq governors: performance powersave
  current policy: frequency should be within 800 MHz and 3900 MHz.
                  The governor "powersave" may decide which speed to use
  current CPU frequency: 1200 MHz (asserted by call to hardware)
  boost state support:
    Supported: yes
    Active: yes

Що це означає: У вас intel_pstate; вибір governor-ів обмежений і поведінка специфічна для драйвера.
Поточна частота низька, бо політика це дозволяє. Турбо увімкнено.

Рішення: Якщо ви діагностуєте стрибки латентності, зауважте, що powersave під intel_pstate все ще може підсилюватися,
але характеристики розгону відрізняються. Не змінюйте governor-и абияк; спочатку виміряйте.

Task 2: Check min/max frequency policy per CPU

cr0x@server:~$ for f in /sys/devices/system/cpu/cpu*/cpufreq/scaling_{min,max}_freq; do echo "$f: $(cat $f)"; done | head
/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq: 800000
/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq: 3900000
/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq: 800000
/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq: 3900000

Що це означає: ОС дозволяє широкий діапазон частот. Якщо продуктивність усе ще погана, обмеження десь інше
(ліміти потужності, терміка, C-states, контенція).

Рішення: Якщо scaling_max_freq несподівано низький, підозрівайте профіль налаштувань, обмеження в середовищі контейнерів або події обмеження платформи.

Task 3: Inspect turbo/boost status

cr0x@server:~$ cat /sys/devices/system/cpu/cpufreq/boost
1

Що це означає: Турбо/буст увімкнено.

Рішення: Для сервісів, чутливих до латентності, турбо часто допомагає (швидший час обслуговування).
Для детермінованої латентності турбо може додавати теплову варіативність; розгляньте фіксацію політики лише після вимірювань.

Task 4: Verify CPU idle state availability and residency (core C-states)

cr0x@server:~$ sudo cpupower idle-info
CPUidle driver: intel_idle
CPUidle governor: menu
analyzing CPU 0:
  Number of idle states: 4
  Available idle states: POLL C1 C1E C6
  C1: exit latency 2 us
  C1E: exit latency 10 us
  C6: exit latency 85 us

Що це означає: Існує глибокий C6 з ~85 µs латентністю виходу (приклад). Це не катастрофа, але не безкоштовно.

Рішення: Якщо ваш p99 корелює з періодами простою, розгляньте обмеження найглибшого C-state тільки на уражених вузлах і повторне тестування.

Task 5: Check per-state time and usage counts for idle states

cr0x@server:~$ for s in /sys/devices/system/cpu/cpu0/cpuidle/state*; do \
  echo "$(basename $s) name=$(cat $s/name) disable=$(cat $s/disable) time=$(cat $s/time) usage=$(cat $s/usage)"; \
done
state0 name=POLL disable=0 time=122 usage=18
state1 name=C1 disable=0 time=983421 usage=24011
state2 name=C1E disable=0 time=221934 usage=9120
state3 name=C6 disable=0 time=55290321 usage=110432

Що це означає: CPU0 проводить багато часу в C6. Це добре для енергії. Це може бути погано для латентності при пробудженні.

Рішення: Якщо бачите хвостову латентність, це ваш підозрюваний номер один. Далі зіставте з метриками додатку та перериваннями.

Task 6: Check package C-state residency (Intel, via turbostat)

cr0x@server:~$ sudo turbostat --Summary --quiet --show PkgWatt,PkgTmp,Pkg%pc2,Pkg%pc6,Pkg%pc10 --interval 1 --num_iterations 3
PkgWatt  PkgTmp  Pkg%pc2  Pkg%pc6  Pkg%pc10
  32.15     54      2.12     8.41     61.77
  28.02     52      1.88     7.96     68.10
  35.44     55      2.30     9.02     58.33

Що це означає: Пакет часто досягає PC10 (глибокий сон). Споживання низьке. Чудово для ефективності.
Також класична причина «холодного» стартового латенсу при пробудженні.

Рішення: Якщо ви запускаєте ноди з малою латентністю, розгляньте обмеження пакетних C-states або використання профілю з низькою латентністю на таких вузлах.
Якщо ви запускаєте батчі — святкуйте й рухайтеся далі.

Task 7: Look for power limit and throttling signals (Intel RAPL / thermal)

cr0x@server:~$ sudo turbostat --quiet --show Bzy_MHz,Avg_MHz,Busy%,CoreTmp,PkgTmp,PkgWatt,CorWatt,GFXWatt --interval 1 --num_iterations 2
Bzy_MHz  Avg_MHz  Busy%  CoreTmp  PkgTmp  PkgWatt  CorWatt  GFXWatt
   4200     1850  22.15       72      79    165.2     92.1     0.0
   4100     1902  23.40       74      81    165.0     93.0     0.0

Що це означає: Boost-частоти є, але пакетна потужність висока. Якщо температура зросте, може початися троттлінг.

Рішення: Якщо продуктивність нестабільна під навантаженням, перевірте охолодження, ліміти потужності і стійку поведінку турбо, перш ніж звинувачувати ядро.

Task 8: Confirm kernel tick mode and timer behavior (idle disruption)

cr0x@server:~$ grep -E 'NO_HZ|CONFIG_HZ' -n /boot/config-$(uname -r) | head -n 5
114:CONFIG_HZ=250
501:CONFIG_NO_HZ_COMMON=y
504:CONFIG_NO_HZ_IDLE=y
507:CONFIG_NO_HZ_FULL is not set

Що це означає: Tickless idle увімкнено (NO_HZ_IDLE), що допомагає досягати глибших C-states. Не повністю безтаймерний режим.

Рішення: Якщо ваше навантаження потребує стабільної низької латентності, ви можете віддати перевагу меншій кількості глибоких переходів у політиці, а не обов’язково зміні конфігурації ядра.

Task 9: Identify interrupt hotspots that prevent idle or cause wake storms

cr0x@server:~$ sudo cat /proc/interrupts | head -n 15
           CPU0       CPU1       CPU2       CPU3
  0:         21         18         19         22   IO-APIC   2-edge      timer
  1:          0          0          0          0   IO-APIC   1-edge      i8042
 24:     883421     102331      99321      90122   PCI-MSI  327680-edge  eth0-TxRx-0
 25:     112331     843221     121112     110998   PCI-MSI  327681-edge  eth0-TxRx-1

Що це означає: Черги NIC завантажені на певних CPU. Це може не дозволяти ядрам простоювати і може викликати сплескові пробудження.

Рішення: Розгляньте налаштування irq affinity (або поведінку irqbalance), якщо бачите гарячі точки на одному ядрі або стрибки латентності, що збігаються з перериваннями.

Task 10: Check irqbalance status and whether it’s fighting your pinning

cr0x@server:~$ systemctl status irqbalance --no-pager
● irqbalance.service - irqbalance daemon
     Loaded: loaded (/lib/systemd/system/irqbalance.service; enabled; preset: enabled)
     Active: active (running) since Tue 2026-01-10 08:21:10 UTC; 2h 12min ago
       Docs: man:irqbalance(1)
   Main PID: 912 (irqbalance)

Що це означає: irqbalance активний. Добрий стандарт — якщо не робите ручне прив’язування IRQ для низької латентності і забули його відключити.

Рішення: Якщо вам потрібна сувора ізоляція CPU, або налаштуйте заборонені CPUs для irqbalance, або вимкніть його і управляйте афінністю вручну.

Task 11: See if a tuning profile is enforcing aggressive power savings

cr0x@server:~$ tuned-adm active
Current active profile: virtual-guest

Що це означає: Активний tuned-профіль може змінювати governor і інші параметри, що впливають на латентність.

Рішення: Для хостів баз даних або сервісів, чутливих до латентності, протестуйте latency-performance (або рекомендований вендором профіль) на канарковому вузлі.

Task 12: Verify current governor quickly across all CPUs

cr0x@server:~$ grep -H . /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null | head
/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor:powersave
/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor:powersave
/sys/devices/system/cpu/cpu2/cpufreq/scaling_governor:powersave
/sys/devices/system/cpu/cpu3/cpufreq/scaling_governor:powersave

Що це означає: Усі CPU в режимі powersave.

Рішення: Якщо ви ганяєтеся за регресіями латентності, переключіть один хост у performance тимчасово і виміряйте p99. Не розгортайте по флоту, керуючись відчуттями.

Task 13: Temporarily change governor (and understand what you’re risking)

cr0x@server:~$ sudo cpupower frequency-set -g performance
Setting cpu: 0
Setting cpu: 1
Setting cpu: 2
Setting cpu: 3

Що це означає: Ви запросили governor performance. На intel_pstate це змінює поведінку політики, а не встановлює фіксований такт.

Рішення: Використовуйте це як контрольований експеримент. Якщо латентність суттєво покращиться і енергобюджет дозволяє, розгляньте застосування профілю через tuned, а не хаотичні зміни.

Task 14: Limit deepest C-state (surgical test, not a lifestyle)

cr0x@server:~$ echo 1 | sudo tee /sys/devices/system/cpu/cpu0/cpuidle/state3/disable
1

Що це означає: Ви відключили один стан простою (тут state3 може бути C6). Це змушує CPU0 переходити в менш глибокий сон.

Рішення: Якщо p99 покращиться і споживання зросте прийнятно, застосуйте це персистентно (аргументи ядра, tuned або systemd unit) і задокументуйте.

Task 15: Check for virtualization effects: are you tuning the guest while the host decides?

cr0x@server:~$ systemd-detect-virt
kvm

Що це означає: Ви віртуалізовані. Гостьові налаштування живлення можуть мати обмежений ефект; політика хоста і планування гіпервізора важливіші.

Рішення: Якщо вам потрібна поведінка з низькою латентністю, працюйте з командою платформи: прив’язка CPU, governor на хості і політика C-states — реальні важелі.

Task 16: Check CPU pressure and scheduling contention (because “idle” can be a lie)

cr0x@server:~$ cat /proc/pressure/cpu
some avg10=0.00 avg60=0.10 avg300=0.08 total=18873412
full avg10=0.00 avg60=0.00 avg300=0.00 total=0

Що це означає: CPU pressure низький; планувальник не бореться. Якщо латентність погана, зосередьтеся на поведінці пробудження/сну, перериваннях, IO або блокуваннях.

Рішення: Якщо some або full високі, не гоніться спочатку за C-states — виправте контенцію, CPU-ліміти або галасливих сусідів.

Швидкий план діагностики

Ось порядок, який я використовую, коли хтось каже «затримки підскакують, коли машина переважно проста» або «CPU низький, але все повільно».
Він оптимізований для швидкого знаходження вузького місця, а не для того, щоб ви відчували себе розумними.

First: decide if you’re chasing CPU power behavior or something else

  1. Перевірте CPU pressure (контенція планувальника):
    якщо PSI високий, ви не «в прості», вас перевантажили або обмежили.
  2. Перевірте чергу виконання і steal time (особливо в VM):
    низька завантаженість може співіснувати з великою латентністю, якщо вас чекають у плануванні.
  3. Перевірте iowait і латентність сховища:
    багато «простою CPU» насправді означає «чекає на IO».

Second: confirm what power policy is active

  1. Драйвер + governor через cpupower frequency-info.
  2. Турбо увімкнено? через /sys/devices/system/cpu/cpufreq/boost.
  3. Тунінг профіль або вендорський сервіс, що нав’язує політику.

Third: measure C-state residency and wake-related disruption

  1. Використання/час по core C-state через /sys/.../cpuidle або cpupower idle-info.
  2. Пакетні C-states через turbostat (якщо доступно).
  3. Гарячі точки переривань через /proc/interrupts і інструменти для афінності IRQ.

Make one change at a time, on one node, with a timer

Найшвидший спосіб витратити тиждень — перемикати BIOS-настройки, параметри ядра і tuned-профілі в одному оці
технічного вікна. Змінюйте по одному, вимірюйте p95/p99 і споживання/терміку, потім приймайте рішення.

Три міні-історії з корпоративних фронтів

Mini-story 1: The incident caused by a wrong assumption

Команда розгорнула новий «легкий» внутрішній API-шлюз. Він був ефективний: низький CPU, короткі сплески, багато мережевих переривань.
На дашбордах завантаження CPU трималося в межах 15–25%. Всі віталися з тим, що не передпродукували.
Потім p99 затримка подвоїлася у годину низького навантаження, саме коли трафік спав.

Перше припущення було класичним: «менше навантаження — більше запасу». Але сервіс був сплесковим.
У тихі періоди CPU заходили в глибокі пакетні C-states. Коли приходив наступний сплеск, обробка запиту платила за пробудження
плюс за латентність розгону частоти. Індивідуально маленькі затримки, разом — некрасиво.

Друге припущення: «Ми в performance governor, отже частота висока.» Насправді — ні.
Половина флоту мала інший профіль BIOS. Ті хости дозволяли глибші пакетні стани і мали більш енергетично-орієнтовану політику.
Флот був гетерогенний, а балансувальник навантаження щасливо змішував хости з різною поведінкою при пробудженні.

Виправлення не було героїчним. Вони стандартизували прошивкові профілі, потім канарили tuned-профіль з низькою латентністю лише на вузлах шлюзу.
Для батч-воркерів глибокий сон зберегли. Латентність стабілізувалася, енергія залишилася в межах, і інцидент закінчився не постмортем-романом,
а коротким чеклистом, доданим до процесу провізування.

Mini-story 2: The optimization that backfired

Команда зі зберігання (думаємо: розподілена блокова служба) захотіла урізати споживання. Вони примусово увімкнули глибші C-states і встановили governor-и powersave по всіх
нодах зберігання. На папері це було відповідально: ноди здебільшого чекали на IO, і CPU не виглядав завантаженим.

Що вони пропустили — так це поведінку зберігання під змішаним навантаженням. Шляхи завершення IO чутливі до латентності і керовані перериваннями.
Сервіс тихо сидів, а потім різко опрацьовував шквал завершень, перевірок контрольної суми і мережевих відповідей.
З глибокими C-states латентність від переривання до обробника зростала. З агресивним масштабуванням частоти ядра починалися повільно, а потім розганялися.

Наслідок був дивним: середня латентність трималась добре, але хвостова латентність і джиттер стали жорстокими.
Клієнти повторювали запити. Повтори спричиняли мікросплески. Мікросплески ще більше змушували CPU переходити між сном і пробудженням.
Зміна «заощадження енергії» створила петлю зворотного зв’язку, яка витрачала і енергію, і час.

Вони відкочували зміни на фронтендах зберігання, але зберегли енергозбереження для фонових компакцій.
Справжній урок — охоплення: політика живлення залежить від робочого навантаження. Застосовуйте її за ролями, а не за кластером, і завжди дивіться p99 і показники повторів.

Mini-story 3: The boring but correct practice that saved the day

Інша компанія керувала Kubernetes-флотом з мішаними поколіннями інстансів. Їхня платформа зробила щось надзвичайно непривабливе:
вони вели матрицю апаратних можливостей і тест провізування, який записував доступність C-states, статус турбо і резидентність простою.
Кожне оновлення BIOS мало пройти ті самі тести перш ніж потрапити в золотий образ.

Одного кварталу оновлення прошивки вендора змінило значення за замовчуванням для пакетних C-state лімітів.
Нічого не зламалося відразу. Ось у чому хитрість — такі зміни не завжди голосно ламають систему. Вони просто змінюють характеристики латентності.

Їхні тести це вловили, бо зафіксована резидентність пакетних C-states суттєво змінилася на простих нодах.
Не довелося чекати, поки клієнт поскаржиться. Вони призупинили розгортання, підправили політику прошивки і задокументували різницю.

Результат був нудний: жодного інциденту. Платформна команда не отримала похвали.
Але команді додатків ніколи не довелося вивчати пакетні C-states о 3:00 ночі, що й є найвищою формою операційного успіху.

Жарт №2: Найкраща зміна в енергоменеджменті — та, що ніколи не потрапляє на слайди постмортему.

Поширені помилки (симптоми → корінь → виправлення)

1) “CPU is low but p99 latency is high”

Симптоми: низька середня завантаженість CPU; великі пікові хвостові затримки у тихі періоди; краща латентність під стабільним навантаженням.

Корінь: глибокі C-states і/або агресивне масштабування частоти спричиняють штрафи на пробудження та розгін; сплесковий трафік викликає повторні переходи.

Виправлення: виміряйте резидентність C-state (ядра і пакет). Проведіть канарку з профілем низької латентності або обмежте найглибші C-states на уражених вузлах.
Переконайтесь у консистентності BIOS-профілів по флоту.

2) “Frequency stuck low even under load”

Симптоми: cpupower frequency-info показує низьку поточну частоту; пропускна здатність нижча за очікувану; температура CPU помірна.

Корінь: масштабування максимальної частоти обмежене політикою, взаємодією квот контейнера або платформними лімітами потужності.

Виправлення: перевірте scaling_max_freq і tuned-профіль; підтвердіть турбо; інспектуйте ліміти потужності/троттлінг через turbostat.
У контейнерах перевірте CPU quota і cpuset-призначення.

3) “Performance improved on one node but not another”

Симптоми: той самий софт, різна латентність; зміни налаштувань працюють непослідовно по хостах.

Корінь: гетерогенні прошивкові дефолти, відмінності мікрокоду або різні драйвери частоти (intel_pstate vs acpi-cpufreq).

Виправлення: уніфікуйте BIOS-настройки; забезпечте консистентні параметри ядра; інвентаризуйте вибір драйверів і версії мікрокоду.

4) “IRQ storms prevent idle and waste power”

Симптоми: пакет ніколи не доходить до глибоких C-states; підвищене споживання в простої; певні CPU показують величезні лічильники переривань.

Корінь: дисбаланс афінності переривань, неправильно налаштовані черги NIC, шумні пристрої або поведінка таймерів.

Виправлення: інспектуйте /proc/interrupts; налаштуйте афінність IRQ; сконфігуруйте кількість черг належним чином; перевірте налаштування irqbalance.

5) “Disabled C-states and now throughput got worse”

Симптоми: збільшилось споживання; з’явився троттлінг по терміці; стійка продуктивність знизилась після короткого початкового буста.

Корінь: відключення економії підвищує базову температуру/споживання, зменшуючи турбо-головку і викликаючи троттлінг.

Виправлення: не відключайте глибокі стани по всьому флоту. Використовуйте політики за роллю. Моніторте терміку і пакетну потужність; прагніть до стабільності, а не максимуму тактів.

6) “We pinned CPUs, but latency still jitters”

Симптоми: налаштована ізоляція CPU; все одно спостерігається джиттер; час від часу довгі хвости.

Корінь: менеджмент живлення все ще переходить ядра/пакет; переривання потрапляють на ізольовані CPU; конкуренція по гіперпотоку.

Виправлення: узгодьте афінність IRQ з ізоляцією; розгляньте обмеження глибоких C-states для ізольованих ядер; перевірте політику SMT для критичних по латентності навантажень.

Чеклисти / покроковий план

Checklist A: Standardize a fleet power baseline (the boring part that prevents surprises)

  1. Зробіть інвентаризацію моделей CPU, версій мікрокоду і статусу віртуалізації по вузлах.
  2. Запишіть драйвер частоти (intel_pstate/acpi-cpufreq) і governor-и в систему конфігурації.
  3. Задокументуйте налаштування BIOS/UEFI (обмеження C-state, турбо, EPB) для кожного апаратного покоління.
  4. Визначте політики за ролями: критичні за латентністю, збалансовані, батч/ефективність.
  5. Забезпечте застосування tuned-профілів або еквіваленту через автоматизацію; без ручних «сніжинок».
  6. Періодично знімайте резидентність пакетних C-states і ват на канаркових ідлах, щоб виявляти відхилення після оновлень прошивки.

Checklist B: Tune a latency-sensitive service node (safely)

  1. Базові виміри: зафіксуйте p95/p99, частоту помилок/повторів і споживання енергії в простої і під типовим сплеском.
  2. Підтвердіть, що це не контенція CPU: перевірте PSI CPU і черги виконання.
  3. Виміряйте резидентність пакетних C-states на простому і під сплеском.
  4. Канарка: змініть tuned-профіль або governor на одному вузлі.
  5. Якщо ще є сплески, протестуйте обмеження найглибшого C-state (тимчасово) і повторіть виміри.
  6. Підтвердіть терміки і стійкі ліміти потужності; слідкуйте за троттлінгом.
  7. Розгортайте за роллю, а не по флоту. Документуйте політику з «чому», а не лише «що».

Checklist C: Tune an efficiency-first batch worker node

  1. Підтвердіть, що навантаження орієнтоване на пропускну здатність і толерує джиттер.
  2. Дозвольте глибокі пакетні C-states і збалансовані governor-и.
  3. Стежте за «бурями» переривань, що не дають пакету заснути (марні ватти).
  4. Моніторте енергію на завдання (або на оброблені GB), а не лише час виконання.

FAQ

1) Are P-states and C-states independent?

Переважно так, але не повністю. C-states визначають, що відбувається під час простою; P-states — продуктивність під час роботи.
На практиці вони взаємодіють через терміку і ліміти потужності: глибший простій може покращити турбо-головку, а відключення простою може зменшити стійкий буст.

2) Should I always use the performance governor on servers?

Ні. Для фронтендів, чутливих до латентності, це може допомогти. Для батч-флотів це часто марнотратно.
Також на intel_pstate performance не означає «фіксований максимум». Це означає більш агресивну політику.
Приймайте рішення за роллю і вимірюйте p99 та ватти.

3) If C-states add latency, why not disable them everywhere?

Бо ви заплатите енергією, теплом і іноді троттлінгом — плюс зменшиться турбо-головка.
Вимикання глибоких C-states може бути інструментом для конкретних ролей. Рідко це гарний дефолт для весього флоту.

4) Why does latency get better under steady load?

Під стабільним навантаженням ядра залишаються в C0 і частоти стабілізуються на вищих рівнях. Ви уникаєте витрат на пробудження і розгін.
Сплескові навантаження повторно платять ці витрати, і хвостова латентність страждає.

5) How do I know whether the OS or hardware is controlling frequency?

Почніть з cpupower frequency-info, щоб побачити драйвер. На сучасних Intel intel_pstate в active режимі означає, що апарат відіграє велику роль.
Також зверніть увагу, чи поточна частота «asserted by call to hardware» у виводі.

6) Does virtualization change the story?

Так. «Простой» гостя опосередковується гіпервізором. Частота і глибокий пакетний сон зазвичай контролюються хостом.
Якщо ви налаштовуєте в гості і не бачите результатів, це не через невдачу — ви просто не тягнете потрібні важелі.

7) What’s the difference between core C-states and package C-states operationally?

Core C-states впливають на глибину сну одного ядра і латентність виходу. Пакетні стани впливають на компоненти на рівні сокета і можуть економити значно більше енергії.
Пакетні стани також можуть давати більш помітні штрафи на «перший запит після простою», залежно від платформи.

8) Can interrupt tuning fix C-state-related latency?

Іноді. Якщо переривання постійно будять ядра, ви побачите марні втрати енергії і джиттер.
Якщо переривання зосереджені на кількох CPU, ці CPU можуть ніколи не спати, тоді як інші йдуть у глибокий сон, створюючи нерівномірну поведінку відповіді.
Балансування або прив’язка переривань може стабілізувати латентність.

9) How do I decide between “low latency” and “energy efficient” modes?

Керуйтеся SLO і моделлю вартості вашої робочого навантаження. Якщо у вас суворі p99 цілі і сплесковий трафік, надавайте перевагу низькій латентності на відповідних вузлах.
Якщо у вас батчі або еластичні черги, надавайте перевагу ефективності. Уникайте змішування політик в одному пулі за одним балансувальником.

10) What’s a safe first experiment if I suspect C-states?

Канарка одного вузла: зніміть базові метрики, потім переключіться на tuned-профіль з низькою латентністю або тимчасово обмежте найглибший стан простою.
Якщо p99 покращується без троттлінгу або неприйнятного зростання споживання — ви довели причинно-наслідковий зв’язок.

Висновок: практичні наступні кроки

«Простой» — це не нейтральний стан. Це активне політичне рішення, прийняте шарами силікону, прошивки та коду ядра — кожен намагається зекономити енергію,
іноді крадучи ваш бюджет латентності в процесі.

Наступні кроки, які дійсно працюють у продакшені:

  1. Виміряйте перед налаштуванням: зберіть драйвер/владний governor, резидентність C-state і p95/p99 латентність на канарковому вузлі.
  2. Уніфікуйте політику прошивки: неконсистентні BIOS-дефолти — мовчазний вбивця флоту.
  3. Розділяйте за ролями: вузли з низькою латентністю і вузли з оптимізацією енергії не повинні мати одну й ту ж політику.
  4. Робіть зміни відкотними: перемикання через tuned-профілі або керування конфігурацією, а не ручні SSH-зміни.
  5. Слідкуйте за хвостовою латентністю і повторами: середні значення збрехають вам з прямим виразом обличчя.
← Попередня
Кеш CPU (L1/L2/L3) простими словами: чому перемагає пам’ять
Наступна →
NTP між офісами: дрібниця, яка ламає AD, VPN і сертифікати

Залишити коментар