Силіконна лотерея: чому ідентичні CPU працюють по-різному

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

Ви купили ту ж саму модель двічі. Така сама ревізія (нібито). Та сама модель материнської плати. Та сама пам’ять. Та сама образ операційної системи. І все одно один вузол завжди «той швидкий», а інший — вузол, якого всі уникають. Ви бачите це в бенчмарках, у хвостовій латентності, у часі компактації, у тривалості CI, у запитах «чому цей под завжди повільний».

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

Що насправді означає «силіконна лотерея» (і чого вона не означає)

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

У колах оверклокерів лотерею часто трактують як: «наскільки високо можна розігнати цей чіп?» В операційній практиці дорожча версія питання звучить так: «чому вузол A тримає вищу пропускну здатність і меншу хвостову латентність при тому ж навантаженні?»

Що це таке

  • Різні криві напруга/частота: Один чіп потребує більшої напруги, щоб утримувати задану частоту; інший — менше. Це змінює тривалість бусту при наявності лімітів потужності/термального режиму.
  • Різний тепловиділення при тій самій роботі: Витоки та ефективність варіюються. «Гарячий» чіп досягає термальних лімітів раніше, знижує частоти, і ваші SLO це помічають.
  • Різна поведінка при векторних навантаженнях: Зсуви частоти під AVX2/AVX-512 та обмеження по струму можуть кардинально змінити стійку продуктивність.
  • Різна толерантність до недовольта/оверклокінгу: У дата-центрах цього в більшості випадків уникають, але деяка поведінка успадковується через заводські налаштування BIOS.

Чим це не є

  • Не доказ, що ваш постачальник «продав вам поганий CPU», якщо ви не бачите нестабільності, WHEA/MCE-шторми або падіння продуктивності поза сімейством чіпів.
  • Не виправдання ігнорувати енергоменеджмент. Більшість скарг на «лотерею» — це насправді неправильно встановлені PL1/PL2, надто агресивні C-states або оновлення BIOS, яке змінило правила посеред сезону.
  • Не тільки про GHz. Резидентність кешу, uncore-частота, поведінка контролера пам’яті й топологія NUMA часто важать більше за заголовкові частоти для реальних сервісів.

Чому продуктивність відрізняється: реальні механізми

1) Бінування та вихід придатних кристалів: «одна модель» вже є групуванням

Вендори процесорів не виробляють «i9» або «Xeon» напряму. Вони виробляють пластини, а потім тестують і сортують кристали в SKU залежно від того, що кожен кристал може стабільно робити в межах енергетичного/термального конверта. Бінування пояснює, чому два дієси з однієї пластини можуть стати різними продуктами — і чому два дієси всередині одного SKU все одно можуть відрізнятися.

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

2) Буст умовний, і умови ніколи не ідентичні

Сучасні CPU не мають «однієї частоти». Вони мають політики. Турбо/Boost залежить від:

  • Кількості активних ядер
  • Температури
  • Пакетних лімітів потужності (PL1/PL2/Tau на багатьох Intel-платформах; PPT/TDC/EDC на багатьох AMD-платформах)
  • Обмежень струму (VRM і роз’ємні обмеження)
  • Класу навантаження (скалярні vs векторні)
  • Поведінки планувальника ОС (parking ядер, пакування SMT, локальність NUMA)

Якщо ви думаєте, що купили «3.2 GHz», ви придбали CPU, який інколи працюватиме на 3.2 GHz, торгуючись з фізикою, прошивкою та повітряними потоками вашого дата-центру.

3) Постачання живлення: VRM, прошивка та «дефолти», що не є консистентними

На серверах CPU — лише частина системи. VRM матплати, ревізії прошивки та заводські налаштування визначають, що означає «ліміт потужності». Дві ідентичні плати все одно можуть поводитись по-різному, бо:

  • Одна має новіший BIOS з іншими енергетичними таблицями.
  • Одна має іншу конфігурацію BMC (криві вентиляторів, теплові політики).
  • Одна має трохи гірший контакт або нерівномірний шар термопасти (так, таке буває).
  • Одна стоїть у «поганому повітрі» поруч із гарячою зоною в стійці.

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

4) Термодинаміка: найшвидший CPU — той, що залишається холодним

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

  • Нижча стійка пропускна здатність (очевидно)
  • Вища хвостова латентність (найнеприємніше)
  • Зміщення результатів бенчмарку з часом (ефекти розігріву)

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

5) Зсуви під AVX/вектори: «один і той самий CPU», але різна ефективна частота під реальним кодом

Векторні інструкції можуть споживати значно більше струму. Багато платформ застосовують AVX-зсув (зниження частоти при AVX2/AVX-512), щоб утримати енергоспоживання та термічні показники. Два вузли, що запускають однакову задачу, можуть відрізнятись, бо:

  • На одному включено AVX-512, на іншому — вимкнено (параметр BIOS або поведінка мікрокоду).
  • Різні ревізії мікрокоду застосовують різні обмеження.
  • Різні бібліотеки (або різні флаги компіляції) обирають різні шляхи інструкцій.

Переклад: ваша «продуктивність CPU» може бути насправді інцидентом вибору математичної бібліотеки.

6) Uncore і пам’ять: невидима половина продуктивності CPU

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

  • Розташування DIMM (1DPC vs 2DPC), ранги, змішані модулі
  • Швидкість пам’яті, знижена через правила населення
  • Різницю топології NUMA (односокетна vs двосокетна, або швидкість інтерконекту сокетів)
  • Налаштування BIOS, що впливають на масштабування uncore-частоти

У системах, орієнтованих на зберігання (бази даних, об’єктні сховища, пошук), варіативність CPU часто проявляється як «I/O повільний», бо процесор витрачає час на стиснення, контрольні суми, шифрування та обробку переривань. CPU — частина вашого конвеєра зберігання, подобається це вам чи ні.

7) Мікрокод і мітегейти: податок на продуктивність може відрізнятись

Оновлення мікрокоду та мітегейти спекулятивного виконання змінили гру після 2018 року. Вплив відрізняється по навантаженнях і конфігураціях. Два «ідентичні» вузли можуть розходитися, якщо:

  • Вони мають різний мікрокод (оновлення пакету, BIOS або постачальницькі для ОС).
  • Параметри завантаження ядра відрізняються (включені/вимкнені мітегейти).
  • Налаштування гіпервізора відрізняються (у віртуалізованих середовищах).

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

8) Планувальник і топологія: ОС може саботувати ваш «ідентичний» хардвер

Linux добре справляється з універсальним плануванням, але він не читає думки. Різниця у продуктивності з’являється, коли:

  • Навантаги перекидаються між NUMA-вузлами.
  • Переривання концентруються на невідповідних ядрах.
  • Губернатор частоти CPU неконсистентний між вузлами.
  • SMT (Hyper-Threading) взаємодіє з вашим навантаженням несподіваним способом.

Якщо ви нічого не фіксуєте, Linux все одно прийматиме рішення. Ці рішення не завжди ті, які ви б прийняли тверезо.

Жарт №1: Силіконна лотерея — це як найняти двійнят і виявити, що одне з них все ще відповідає на пошту.

Факти та історія: як ми сюди дійшли

  • Факт 1: Бінування чіпів — стандартна практика десятиліть: вендори тестують кристали й сортують їх за стабільною частотою, напругою і толерантністю дефектів.
  • Факт 2: Перехід від фіксованих частот до агресивного турбо-бусту перетворив невеликі електричні відмінності на помітні розбіжності продуктивності — бо буст opportunistic.
  • Факт 3: Dennard scaling (ера, коли потужність залишалася керованою при зменшенні транзисторів) фактично закінчилася в середині 2000-х, що підштовхнуло вендорів до динамічного енергоменеджменту й багатоядерних дизайнів.
  • Факт 4: Правила мульти-ядрового турбо часто залежать від «скільки ядер активні», тож один і той самий CPU може поводитися як кілька різних CPU залежно від планування.
  • Факт 5: AVX-512 (де є) часто викликає нижчі стійкі частоти; деякі оператори вимикають його, коли він шкодить змішаним навантаженням більше, ніж допомагає.
  • Факт 6: Мікрокод може суттєво змінювати характеристики продуктивності: не лише мітегейти безпеки, але й поведінку бусту та обмеження стабільності.
  • Факт 7: Серверні вендори часто відправляють BIOS за замовчуванням, налаштований на «безпечні» терміни та акустику, а не на консистентну низьку латентність.
  • Факт 8: Правила населення пам’яті (кількість DIMM, ранги) можуть змусити знижувати частоту пам’яті; дві «однакові» системи можуть мати різну пропускну здатність лише через конфігурацію.
  • Факт 9: cpufreq-скейлінг і C-states в Linux можуть створювати помітні джитери; вузол з глибокими станами простою може виглядати «повільнішим» під імпульсним навантаженням.

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

Швидкий план діагностики: знайдіть вузьке місце за кілька хвилин

Перше: доведіть, що це варіативність CPU, а не варіативність навантаження

  1. Порівняйте подібні запити (той самий розмір введення, та сама гілка коду). Якщо цього не можливо — зупиніться й інструментуйте.
  2. Перевірте використання CPU проти черги виконання: високе завантаження з великою чергою run queue вказує на насичення CPU; низьке завантаження з латентністю — на затримки в іншому місці.
  3. Шукайте тротлінг: термальний, енергетичний або обмеження частоти.

Друге: перевірте три «мовчазні вбивці»

  1. Ліміти потужності (PL1/PL2/PPT) встановлені по-різному на різних вузлах.
  2. Терміка/вентилятори (один сервер гарячіший або вентилятори обмежені).
  3. Дрейф мікрокоду/BIOS (та сама модель, але різна поведінка).

Третє: підтвердіть топологію і політики

  1. NUMA: потоки й пам’ять локальні?
  2. Губернатор і C-states: чи ви міняєте латентність заради невеликої економії енергії?
  3. IRQ affinity: чи мережеві/дискові переривання прикріплені до найгірших ядер?

Четверте: перевірте повторюваним мікробенчмарком

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

Практичні завдання: команди, виводи та рішення (12+)

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

Task 1: Підтвердити модель CPU, stepping та мікрокод

cr0x@server:~$ lscpu | egrep 'Model name|Stepping|Vendor ID|CPU\(s\)|Thread|Core|Socket'
Vendor ID:                           GenuineIntel
Model name:                          Intel(R) Xeon(R) Gold 6338 CPU @ 2.00GHz
CPU(s):                              64
Thread(s) per core:                  2
Core(s) per socket:                  32
Socket(s):                           1
Stepping:                            6
cr0x@server:~$ grep -m1 microcode /proc/cpuinfo
microcode	: 0xd0003a2

Що це означає: Якщо stepping або мікрокод відрізняються між «ідентичними» вузлами, очікуйте відмінності в бусті та мітегейтах.

Рішення: Стандартизувати BIOS + мікрокод по флоту перед тим, як ганятися за примарами в коді застосунку.

Task 2: Перевірити стан мітегейтів ядра (відмінності «податку» на продуктивність)

cr0x@server:~$ grep . /sys/devices/system/cpu/vulnerabilities/*
/sys/devices/system/cpu/vulnerabilities/meltdown: Mitigation: PTI
/sys/devices/system/cpu/vulnerabilities/spectre_v2: Mitigation: Retpolines; IBPB: conditional; STIBP: disabled; RSB filling; PBRSB-eIBRS: Not affected

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

Рішення: Вирівняти параметри завантаження та версії ядра; виміряти перед зміною безпекової постановки.

Task 3: Перевірити консистентність губернатора частоти CPU

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

Що це означає: «powersave» (на деяких системах) може все ще дозволяти буст, але політика й латентність відрізняються. Несумісні губернатори викликають неконсистентну хвостову латентність.

Рішення: Для сервісів, чутливих до латентності, використовуйте performance, якщо немає виміряної причини інакше.

Task 4: Прочитати ефективну частоту і сигнали тротлінгу за допомогою turbostat

cr0x@server:~$ sudo turbostat --Summary --interval 2 --quiet
     PkgTmp  PkgWatt  CorWatt   GFXWatt Avg_MHz  Busy%  Bzy_MHz  IPC
      71      178.3     160.2     0.0    3120    92.4    3375   1.15
      83      205.7     187.9     0.0    2480    96.1    2580   1.08

Що це означає: Якщо Avg_MHz і Bzy_MHz падають при зростанні PkgTmp, у вас термальний тротлінг. Якщо PkgWatt досягає стелі і MHz падає — ви обмежені по потужності.

Рішення: Виправити охолодження або відрегулювати ліміти потужності (в межах вказівок вендора). Не «оптимізуйте застосунок», щоб компенсувати гарячий корпус.

Task 5: Перевірити прапори термального тротлінгу в логах ядра

cr0x@server:~$ sudo dmesg -T | egrep -i 'thrott|thermal|PROCHOT|Package temperature' | tail -n 20
[Mon Jan 12 09:41:08 2026] CPU0: Package temperature above threshold, cpu clock throttled
[Mon Jan 12 09:41:12 2026] CPU0: Package temperature/speed normal

Що це означає: Це визнання CPU, що він уповільнився. Розглядайте це спочатку як апаратну/середовищну проблему.

Рішення: Перевірити профілі вентиляторів, повітряні потоки, пил, прилягання радіатора; розглянути переміщення вузла в стійці для перевірки гарячих зон.

Task 6: Порівняти версії BIOS/прошивки (детектор дрейфу)

cr0x@server:~$ sudo dmidecode -t bios | egrep 'Vendor|Version|Release Date'
Vendor: American Megatrends International, LLC.
Version: 2.3.7
Release Date: 08/14/2025

Що це означає: Різні версії BIOS часто означають різні таблиці бусту, бандли мікрокоду, дефолтні енергетичні налаштування.

Рішення: Оновлюйте/стандарзуйте BIOS свідомо, а не «коли хтось має час». Розглядайте це як продакшн-зміну.

Task 7: Перевірити framework обмеження потужності (RAPL) і виявити капи

cr0x@server:~$ sudo powercap-info -p intel-rapl
Zone intel-rapl:0 (package-0)
  power limit 0: 180.00 W (enabled)  time window: 28.00 s
  power limit 1: 220.00 W (enabled)  time window: 0.00 s

Що це означає: Ці капи можуть відрізнятись між вузлами. Також деякі платформи експонують їх по-різному; відсутність виводу не означає відсутності капів.

Рішення: Якщо один вузол обмежений нижчим лімітом, виправте політику або налаштування BIOS. Не приймайте «таємничо повільний вузол» як долю.

Task 8: Перевірити C-states і політику простою (джитер латентності)

cr0x@server:~$ cat /sys/module/intel_idle/parameters/max_cstate
9
cr0x@server:~$ sudo cpupower idle-info | sed -n '1,25p'
CPUidle driver: intel_idle
CPUidle governor: menu
analyzing CPU 0:
  Number of idle states: 10
  state0: POLL
  state1: C1
  state2: C1E
  state3: C3

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

Рішення: Для суворих SLO по латентності обмежте максимальний C-state або використовуйте tuned-профілі — після вимірювання впливу на енергоспоживання.

Task 9: Підтвердити NUMA-розклад і відповідність очікуванням

cr0x@server:~$ numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 128768 MB
node 0 free: 120112 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 129024 MB
node 1 free: 121004 MB

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

Рішення: Фіксуйте пам’ять і CPU для критичних задач; уникайте перекресного NUMA-трафіку, якщо ваше навантаження не розроблене для цього.

Task 10: Виявити швидкість пам’яті і зниження через населення DIMM

cr0x@server:~$ sudo dmidecode -t memory | egrep -i 'Locator:|Speed:|Configured Memory Speed' | head -n 20
Locator: DIMM_A1
Speed: 3200 MT/s
Configured Memory Speed: 2933 MT/s
Locator: DIMM_B1
Speed: 3200 MT/s
Configured Memory Speed: 2933 MT/s

Що це означає: DIMM-и можуть рекламувати 3200, але працювати на 2933 через правила населення. Інший вузол може працювати на 3200, даючи йому реальну перевагу по пропускній здатності.

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

Task 11: Перевірити помилки CPU або machine checks (поганий силікон vs погана платформа)

cr0x@server:~$ sudo journalctl -k | egrep -i 'mce|machine check|whea|edac' | tail -n 20
Jan 12 09:12:10 server kernel: mce: [Hardware Error]: CPU 0: Machine Check: 0 Bank 7: b200000000070005
Jan 12 09:12:10 server kernel: mce: [Hardware Error]: TSC 0 ADDR fef1c140 MISC d012000100000000

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

Рішення: Ескалювати апаратній підтримці. Замінити CPU або плату. Не дозволяйте поганому вузлу гнити у флоті.

Task 12: Переглянути розподіл переривань (мережеві/дискові вузькі місця, що виглядають як варіативність CPU)

cr0x@server:~$ cat /proc/interrupts | head -n 15
           CPU0       CPU1       CPU2       CPU3
  24:   9182736          0          0          0  IR-PCI-MSI  524288-edge      nvme0q0
  25:         12          0          0          0  IR-PCI-MSI  524289-edge      eth0-TxRx-0
  26:         10          0          0          0  IR-PCI-MSI  524290-edge      eth0-TxRx-1

Що це означає: Якщо більшість переривань потрапляє на CPU0, ви отримуєте точкові навантаження, конкуренцію за кеш і «цей вузол повільніший». Це не CPU; це ваша інфраструктура переривань.

Рішення: Налаштувати irqbalance або вручну прив’язати IRQ для високопропускних NIC/NVMe шляхів.

Task 13: Перевірити навантаження планувальника: черга виконання і переключення контекстів

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 120112  10132 500112    0    0     1     3 1200 2800 22  7 71  0  0
 9  0      0 119980  10132 500200    0    0     0     0 5100 9800 74 14 12  0  0

Що це означає: Високе r (run queue) з низьким id означає конкуренцію за CPU. Високе cs може вказувати на надмірні переключення контекстів (погане прикріплення, зайві потоки або шумні сусіди).

Рішення: Правильно підігнати пул потоків; зафіксувати критичні потоки; зменшити фоновий шум на вузлах, чутливих до латентності.

Task 14: Перевірити фактичну поведінку частоти по ядрах під навантаженням

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

11:02:14 AM  CPU   %usr  %sys  %iowait  %irq  %soft  %idle
11:02:15 AM  all  62.10  11.22     0.12  0.00   0.55  25.99
11:02:15 AM    0  92.00   6.00     0.00  0.00   2.00   0.00

Що це означає: Одне ядро, що загрузло (часто CPU0), натякає на концентрацію IRQ або одно-потокову проблему. Скарги «CPU повільний» часто ховають одне гаряче ядро.

Рішення: Виправте прив’язку переривань і паралелізм застосунку перед тим, як звинувачувати силікон.

Task 15: Переконатися, що ваше навантаження не використовує різні набори інструкцій мовчки

cr0x@server:~$ lscpu | grep -i flags | tr ' ' '\n' | egrep 'avx|avx2|avx512' | head
avx
avx2
avx512f
avx512dq

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

Рішення: Стандартизувати експозицію можливостей CPU у гіпервізорі/контейнерах; за потреби зафіксувати таргети збірки.

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

Міні-історія 1: Інцидент через неправильне припущення

Середня SaaS-компанія розгорнула нову партію «ідентичних» обчислювальних вузлів для API з чутливістю до латентності. Така сама модель CPU, така сама оперативна пам’ять, такий самий NIC. Вони додали їх у той самий пул вузлів Kubernetes і очікували лінійного зростання ємності.

Протягом тижня у ротації on-call з’явився шаблон: p95 латентності в нормі, але p99.9 стрибав щоразу, коли HPA розгортала поди на підмножині нових вузлів. Графіки виглядали як поганий ЕКГ. Підозра спочатку була на «шумного сусіда». Далі — «регресія GC». Два дні вони виконували звичний танець: профілювання купи, flame graphs і обережні відкати.

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

Вони підтвердили це, порівнявши turbostat під ідентичним генератором навантаження, зафіксованим на тій самій кількості потоків. «Повільні» вузли досягали пакетного ліміту потужності, потім частоти падали. Жодних збоїв. Жодних очевидних помилок. Просто тихо повільніше.

Вирішення було нудним і ефективним: стандартизувати BIOS і політику енергії. Ємність повернулася, хвостова латентність стабілізувалася, і команда додала в постмортем дію: «Перевірки дрейфу флоту обов’язкові перед додаванням вузлів у латентні пули». Найкраще: це запобігло тій самій помилці під час наступного оновлення апаратури.

Міні-історія 2: Оптимізація, що вистрілила собі в ногу

Команда платформи даних експлуатувала сервіс, що багато працював з диском: стиснення, контрольні суми та шифрування на шляху I/O. Вони гналися за вартістю на запит. Рахунки за електроенергію росли, і хтось запропонував увімкнути глибші C-states і переключити губернатора на більш «ефективний» режим. Зміна виглядала безпечно: середнє використання CPU було лише 35%, і сервіс мав запас.

За кілька годин після розгортання почали надходити тікети: «завантаження іноді зависає», «завантаження інколи підвисає», а найгірше — «система відчувається липкою». Дашборди показали невелике зростання p50, але p99 і p99.9 виросли суттєво. Явних обмежень не було. Мережа і диск були в порядку. CPU не був завантажений.

Провал стосувався імпульсності. Сервіс мав різкі піки CPU на запиті (крипто/стиснення) і покладався на швидке пробудження CPU, щоб витримати хвостову латентність. Глибокі стани просто укладали CPU на дрімоту. «Середнє» залишалось в нормі, а «найгірший випадок» зрадив їх.

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

Вони відкатили губернатора і обмежили C-states для пулу з латентністю. Споживання енергії трохи зросло. Інциденти значно знизилися. Пізніше вони ввели розділення пулів: енергоефективні вузли для пакетної роботи і вузли, налаштовані на латентність, для інтерактивного трафіку. Так ви робите фінансів і on-call менш сердитими.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

Велике підприємство експлуатувало змішані навантаження: бази даних, пошук і внутрішні системи збірки. Оновлення апаратури були частими, і варіативність очікувалась. Несподівано з’явилося різке падіння пропускної здатності на підмножині реплік бази даних після планового вікна обслуговування — на 15–20%.

Команда не панікувала. У них була нудна практика: кожен вузол мав «відбиток» при постачанні — версія BIOS, мікрокод, стан мітегейтів, губернатор, ліміт C-state, налаштована швидкість пам’яті, NUMA-топологія. Він зберігався поруч із записом у CMDB. Це не було гламурно, але було пошуково.

Вони порівняли відбитки між «хорошими» і «поганими» репліками і знайшли один дрейф: оновлення BIOS змінило тренування пам’яті і на системах з певним населенням DIMM погодило нижчу налаштовану швидкість пам’яті. Частоти CPU були в порядку. Зберігання було в порядку. База даних не була «повільною»; вона частіше чекала пам’ять.

Ремедіація була такою ж нудною: відрегулювати населення DIMM відповідно до рекомендацій вендора та стандартизувати профіль BIOS по сімейству апаратури. Реплікація повернулася до норми.

Нічого з цієї історії не стане вірусним. Але вона врятувала день, бо команда ставилася до продуктивності як до конфігурації, а не як до інтуїції.

Жарт №2: Ніщо не каже «підприємство» краще, ніж вирішення проблеми продуктивності оновленням таблиці в електронній таблиці і доведенням своєї правоти.

Поширені помилки: симптом → корінна причина → виправлення

1) Симптом: Один вузол стабільно на 10–20% повільніший під постійним навантаженням

Корінна причина: Різні ліміти потужності (PL1/PL2/PPT) або турбо-вікно (Tau), часто через відмінності BIOS.

Виправлення: Порівняйте версії BIOS і налаштування powercap; вирівняйте прошивку та профілі енергії; перевірте через turbostat під тим самим генератором навантаження.

2) Симптом: Продуктивність добре стартує, а потім погіршується через 2–5 хвилин

Корінна причина: Термічна насиченість і тротлінг; вентиляційні криві надто консервативні; забиті фільтри; погана циркуляція в стійці.

Виправлення: Перевірити теплові логи і dmesg; перевірити політику вентиляторів BMC; валідувати повітряні потоки; пересісти радіатор при потребі; повторно запустити бенчмарк після прогріву.

3) Симптом: p50 в нормі, p99 жахливий, завантаження CPU не високе

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

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

4) Симптом: Одна «ідентична» VM повільніша за іншу на тому самому хості

Корінна причина: Маскування можливостей CPU, неконсистентне прикріплення vCPU або різний мікрокод/мітегейти хоста.

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

5) Симптом: Пропускна здатність стиснення/шифрування сильно відрізняється між вузлами

Корінна причина: Різні шляхи інструкцій (AVX/AVX2/AVX-512), різні збірки бібліотек або AVX-зсуви, що спрацьовують на одному вузлі частіше.

Виправлення: Підтвердити прапори CPU; стандартизувати бібліотеки і флаги збірки; розглянути вимкнення AVX-512 для змішаних навантажень, якщо він більше шкодить, ніж допомагає.

6) Симптом: «CPU повільний», але лічильники perf показують низький IPC

Корінна причина: Затримки пам’яті, віддалений NUMA-доступ або надто агресивне масштабування uncore-частоти.

Виправлення: Перевірити NUMA-локальність; фіксувати пам’ять; валідувати швидкість пам’яті; налаштувати політику uncore при підтримці платформи; повторити вимірювання.

7) Симптом: Випадкові уповільнення корелюють з активністю зберігання/мережі

Корінна причина: Шторми переривань або IRQ, прикріплені до одного ядра; CPU0 стає «сміттєвим відром».

Виправлення: Вирівняти переривання; перевірити RSS/RPS; розглянути виділення ядер для обробки IRQ на високопропускних коробках.

8) Симптом: Два вузли відрізняються лише після вікна безпеки

Корінна причина: Різні стани мітегейтів, версії ядра або пакети мікрокоду.

Виправлення: Підтвердити статус уразливостей між вузлами; стандартизувати rollout ядра і мікрокоду; бенчмарк критичних шляхів до/після зміни.

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

Чек-лист A: Перед тим, як оголосити «силіконну лотерею» в продакшені

  1. Підтвердьте, що порівнюєте ту ж фазу навантаження (теплий кеш vs холодний кеш має значення).
  2. Перевірте паритет образу ОС: ядро, мікрокод, параметри завантаження.
  3. Перевірте дрейф BIOS/прошивки: версія та профіль налаштувань.
  4. Підтвердьте, що губернатор і політика C-state відповідають класу сервісу.
  5. Виміряйте терміку і тротлінг під стійким навантаженням.
  6. Перевірте ліміти потужності (RAPL / інструменти вендора / BIOS).
  7. Підтвердьте налаштовану швидкість пам’яті і симетрію населення.
  8. Перевірте топологію NUMA і чи навантаження NUMA-aware.
  9. Огляньте розподіл IRQ для гарячих шляхів NIC/NVMe.
  10. Запустіть повторюваний мікробенчмарк з фіксацією на ядрах і NUMA-вузлах.

Чек-лист B: Стандартизувати для передбачуваної продуктивності (гігієна флоту)

  1. Створити hardware+firmware baseline для кожного покоління платформи (версія BIOS, ключові налаштування, мікрокод).
  2. Автоматизувати виявлення дрейфу (щодня або щотижня) і сигналізувати про відмінності, що мають значення: мікрокод, губернатор, мітегейти, швидкість пам’яті.
  3. Розділити пули вузлів за призначенням: batch/ефективність vs latency/консистентність.
  4. Встановити acceptance test: стійке навантаження, термальне вигорання та вимірювання хвостової латентності.
  5. Відслідковувати позицію у стійці та температуру повітря на вході як першокласну метадані для аномалій продуктивності.

Чек-лист C: Коли у вас дійсно є варіативність силікону і її не усунути

  1. Визначити «швидкі» та «повільні» біни за власними бенчмарками флоту (той самий тест, ті ж умови).
  2. Запланувати навантаження відповідно: сервіси, чутливі до латентності, на найбільш консистентні/холодні вузли.
  3. Використовувати маршрутизацію за ресурсами: спрямовувати важкі векторні навантаження подалі від вузлів, що знижують частоту під AVX.
  4. Збільшити запас: не працювати на 85–90% CPU, якщо вам важлива хвостова латентність.
  5. Мати запаси і виводити підозрілі вузли до ротації до того, як вони стануть магнітом для інцидентів.

Питання та відповіді

1) Чи справжня силіконна лотерея, чи це просто шум бенчмарків?

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

2) Скільки варіативності «нормально» між CPU одної моделі?

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

3) Чи це більше важливо для серверів, ніж для десктопів?

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

4) Чи можуть оновлення мікрокоду змінити продуктивність, навіть якщо CPU однаковий?

Так. Мікрокод може змінювати поведінку мітегейтів, охоронні механізми стабільності і часом поведінку бусту. Розглядайте мікрокод як зміну, що впливає на продуктивність, і вимірюйте критичні шляхи до/після оновлення.

5) Чи завжди термальний тротлінг очевидний?

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

6) Чи слід вимкнути C-states і скейлінг частот на всіх вузлах?

Ні. Робіть це там, де це обґрунтовано: пули з вимогливими латентними SLO, системи для високочастотної торгівлі, усе з жорсткими хвостовими вимогами. Для пакетної і пропускної роботи залишати енергоменеджмент увімкненим може бути розумно. Розділяйте пули, замість нав’язувати одну політику всім.

7) Як проблеми з диском/зберіганням можуть бути спричинені варіативністю CPU?

Стиснення, контрольні суми, шифрування, erasure coding, дедуплікація і навіть обробка мережевих пакетів — це робота CPU. CPU, що тримає нижчі частоти під навантаженням, робить «диск I/O» повільнішим, бо конвеєр обробки обмежений процесором.

8) Який найшвидший спосіб визначити, чи ви обмежені енергією чи термікою?

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

9) Чи «ідентичні» CPU більше відрізняються під AVX-навантжаннями?

Можуть, бо AVX підвищує щільність потужності і викликає зсуви та обмеження по струму. Невеликі відмінності ефективності і різна політика прошивки можуть давати більші розриви в стійких частотах під AVX-важкими кодами.

10) Чи варто проводити внутрішнє «бінування» серверів (позначати швидкі/повільні)?

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

Висновок: наступні кроки, що реально зменшують варіативність

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

  1. Стандартизувати прошивку та мікрокод у рамках одного пулу вузлів. Дрейф — ворог передбачуваності.
  2. Вимірювати тротлінг явно (turbostat + логи) замість того, щоб довіряти заголовковим характеристикам.
  3. Розділити пули вузлів за призначенням: налаштовані на латентність vs налаштовані на ефективність. Один розмір ні для кого не підходить.
  4. Перевірити конфігурацію пам’яті (налаштована швидкість, симетрія населення, локальність NUMA). Тут люблять ховатися «проблеми CPU».
  5. Автоматизувати відбитки і оповіщення про дрейф, щоб ви ловили повільний дрейф до того, як він стане шквалом тікетів.

Силіконна лотерея не зникне. Але ви можете припинити дозволяти їй управляти вашим планом ємності і вашим пейджером.

← Попередня
ZFS на Proxmox проти VMFS на ESXi: Снапшоти, продуктивність, відновлення та реальні підводні камені
Наступна →
ZFS offline/online: Використання режиму обслуговування без втрати надлишковості

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