Ви не «відчуваєте» нове покоління CPU тому, що скріншот бенчмарка став гарнішим. Ви відчуваєте його тоді, коли p99 перестає стрибати о 10:03 щодня, коли вузли зберігання перестають відставати при scrub, коли рахунок за електроенергію припиняє рости швидше за кількість співробітників, і коли ваш канал інцидентів знову стає нудним.
Оновлення Zen — від Zen 1 до Zen 4 і варіанту Zen 4c — сповнені змін, які не видно на маркетингових слайдах, але болюче очевидні в продакшені. Це практичний огляд: що фактично змінюється між поколіннями, як це проявляється в реальних системах і як довести це командами команд, а не відчуттями.
Що ви справді відчуваєте: зміни, що впливають на продакшн
Більшість команд купують CPU так само, як купують парасольки: за тим, наскільки вони намочилися минулого разу. Це зрозуміло, але веде до неправильних очікувань. Між поколіннями Zen зміни, які ви відчуваєте, групуються в п’ять категорій:
1) Поведінка хвостової латентності змінюється
Zen — це не просто «більше IPC». Змінюється розмітка кешу, змінюються комплекси ядер, швидкості fabric і контролери пам’яті. Ці речі змінюють форму розподілів латентності. Велике «відчуття» Zen 3 для багатьох латентнісно‑чутливих сервісів було в тому, що між’ядерна комунікація стала менш дивною, бо змістився кордон CCX (детальніше далі). Zen 4 часто відчувається як «те саме, але швидше», поки ви не помітите, що пам’ять і PCIe можуть стати новим «стелею».
2) Рухаються межі пропускної здатності (і вузькі місця теж)
На старіших платформах ви могли бути обмежені CPU. На новіших — без змін у коді — ви можете стати обмеженими пам’яттю або I/O. Коли приходить PCIe 5, канали зберігання можуть переміститися від «PCIe — ліміт» до «прошивка NVMe, налаштування IOMMU або IRQ affinity — ліміт». Оновлення показують, яка частина стеку найповільніше брешеться.
3) Щільність ядер змінює все в операціях
Більша кількість ядер — це не лише вища пропускна здатність. Це більше чутливості до NUMA, більше конфліктів за спільні кеші, більше рішень про маршрутизацію переривань і більше способів нашкодити собі наївним універсальним тюнінгом ядра. Різниця між «швидким CPU» і «швидкою системою» — це чи встигають ваші рішення з урахуванням топології.
4) Енергія та терміни перестають бути фоном
Продуктивність на ват — це те, де Zen тихо вбиває конкурентів у датацентрі. Але більш агресивний turbo і щільніші сокети роблять «охолодження» інженерним параметром, а не після думкою від відділу інфраструктури. Якщо ви колись бачили, як вузол тротлить під тривалим навантаженням і потім поводиться нормально в продакшені — ви зустріли цю проблему.
5) Зрілість прошивки та мікрокоду важать більше, ніж хочеться
Нові платформи виходять з «ранньою особистістю життя». З часом це покращується. Ваша задача — ставитися до BIOS, AGESA і мікрокоду як до продакшн-залежностей. Якщо це звучить дратівливо — так. Також: це дешевше, ніж простої.
Цитата, щоб тримати вас чесними, від Gene Kranz: «Failure is not an option.» Цю фразу часто повторюють; сприймайте її як парафразовану ідею про строгість під тиском, а не як слоган продуктивності.
Жарт №1: Оновлювати CPU, щоб виправити архітектурну проблему — це як купувати швидший принтер, щоб покращити свій почерк.
Факти та контекст, що пояснюють дивні місця
Ви прийматимете кращі рішення, якщо запам’ятаєте кілька конкретних фактів про те, як ми сюди дісталися:
- Zen (2017) був «скиданням» AMD після епохи Bulldozer, повернувши високі IPC‑ядра і знову вийшовши на серйозну серверну конкуренцію.
- EPYC “Naples” (Zen 1) використовував підхід MCM з кількома кристалами; топологія була потужною, але її легко було неправильно налаштувати для NUMA‑чутливих навантажень.
- Zen 2 (2019) перейшов на чиплети: обчислювальні чиплети на 7нм плюс I/O‑діє. Це розділення є фундаментальним для того, що ви відчуваєте пізніше (особливо поведінка пам’яті/I/O).
- Zen 3 (2020) реорганізував ядра та кеш у єдиний 8‑ядерний комплекс на CCD, зменшивши певні штрафи при між’ядерній комунікації.
- Zen 4 (2022) приніс DDR5 і PCIe 5 у мейнстрім EPYC‑платформи, змістивши межу вузьких місць і оголивши неякісні частини I/O‑ланцюга.
- Варіанти з 3D V‑Cache змінили розмову про тюнінг: можна купити кеш замість надії на покращення латентності пам’яті. Це компроміс, який варто кількісно оцінити.
- Мітгації безпеки (епоха Spectre і далі) змінили дефолти ядра та поведінку гіпервізорів; порівняння між поколіннями без урахування цих мітгацій часто є фантазією.
- Linux навчився топології з часом. Покращення планувальника і NUMA‑балансування означають, що «той самий софт, інше ядро» може виглядати як зміна покоління.
- Infinity Fabric і її зв’язок із частотою пам’яті були повторюваною темою; це впливає на міжкристальну латентність і пояснює, чому налаштування пам’яті — не проста галочка.
Zen по поколіннях: зміни, важливі для опсів
Я буду трішки несправедливий до маркетингових назв і зосереджуся на тому, що б’є вас о 2‑й ночі. «Відчуття» кожного покоління — це поєднання дизайну ядер, кешу, пам’яті, I/O і зрілості платформи.
Zen 1 / Zen+ (ера Naples): «Швидко, але топологія вдарить вас, якщо будете вважати її Intel»
Сервери на Zen 1 стали шоком для ринку: багато ядер, багато ліній, гарна продуктивність за долар. Вони також познайомили багато команд з реальністю NUMA. Naples міг поводитися як кілька машин, зʼєднаних болтами, якщо ви не були обережні з наповненням пам’яті та розміщенням процесів.
Що відчуваєте: непередбачувана хвостова латентність при міжсокетному або міжкристальному чаті, і навантаження, які масштабуются до певного моменту — а потім різко падають.
Що робити: вивчіть ваші NUMA‑вузли, зафіксуйте критичні сервіси, і припиніть думати, що «розподілити по всіх ядрах» завжди добре.
Zen 2 (Rome): «Чиплети, краще масштабування і менше сюрпризів — якщо не наситити пам’ять»
Zen 2 зробив чиплетну архітектуру мейнстрімом у серверах. I/O‑діє централізувало контроллери пам’яті і I/O. Це часто робило платформу простішою для розуміння, але також робило пропускну здатність пам’яті спільним ресурсом, який можна швидко витратити при високій кількості ядер.
Що відчуваєте: краща продуктивність на ядро і загалом плавніше масштабування; але пам’яті‑інтенсивні навантаження починають показувати «пропускна здатність — новий CPU».
Що робити: ставте канали пам’яті як ресурс першого рівня. «Більше DIMM» може бути рішенням щодо продуктивності, а не лише ємності.
Zen 3 (Milan): «Об’єднаний CCX: латентність перестає бути “таємничою” для багатьох навантажень»
Великим операційним плюсом Zen 3 було те, що всередині CCD ядра ділились єдиним L3‑кешем замість дрібніших CCX‑сегментів. Це зменшило певні штрафи для потоків, що ділили дані, але випадково опинилися на різних ядрах.
Що відчуваєте: покращення p99 для сервісів з великою кількістю спільного read‑mostly стану (кеші, таблиці маршрутизації, деякі JVM‑навчальні навантаження), і менше «чому перенесення процесу на інше ядро змінює латентність?»
Що робити: перегляньте старі правила pinning. Деякі хаки, потрібні на Zen 1/2, стають зайвими — або навіть шкідливими.
Zen 4 (Genoa): «DDR5 і PCIe 5 зміщують цілі; гучніша енергія, прошивка і тюнінг I/O»
Справжня історія Zen 4 — це платформа: DDR5, PCIe 5 і вищі кількості ядер. Якщо ви працюєте зі зберіганням, мережею або будь‑чим, що по суті «переміщує байти і не повинно чекати», ви це відчуєте.
Що відчуваєте: запас пропускної здатності і можливість консолідувати більше навантажень на сокет — поки обробка переривань, налаштування IOMMU або чутливість до латентності пам’яті не наздоженуть вас.
Що робити: закладіть час на тюнінг BIOS/прошивки і вирівнювання IRQ/NUMA. Очікуйте ранні «квірики» платформи. Плануйте вікна для патчів.
Zen 4c (варіанти з щільними ядрами): «Більше ядер, трохи інша поведінка на ядро; рішення планування важливі»
Варіанти з щільними ядрами створені для максимізації пропускної здатності на стійку та ват. «Відчуття» — ви можете упакувати більше роботи, але треба більш свідомо обирати, які сервіси туди ставити (орієнтовані на пропускну здатність, менш чутливі до латентності), а які — на високочастотні частини.
Що відчуваєте: велика пропускна здатність для паралельних задач, але деякі однопотокові або латентнісно‑чутливі компоненти можуть потребувати ізоляції або інших SKU.
Що робити: розділіть «шар латентності» та «шар пропускної здатності» в плануванні ємності. Не змішуйте їх лише через зручність.
Топологія, NUMA, CCD/CCX: де ховається продуктивність
Якщо ви хочете одну ментальну модель, що пояснює більшість «дивностей» Zen — ось вона: ваш CPU не є монолітом. Це район з обчислювальними острівцями, з’єднаними дорогами. Деякі дороги швидкі. Деякі дороги мають затори. Ваша задача — тримати балакучих сусідів поруч.
Що змінилося між поколіннями Zen
- Zen 1/2: менші домени кешу означали більше промахів між доменами кеша для спільних робочих наборів, що проявлялося як стрибки латентності при зміні розміщення потоків.
- Zen 3: єдиний L3 на CCD зменшив штраф за «два потоки ділять дані, але не ділять шматок кеша». Це практична, вимірювана зміна.
- Zen 4: поліпшення платформи підвищують стелі, але зростає складність топології. Кількість ядер зростає, змінюються канали пам’яті, і в залежності від BIOS та SKU у вас може з’явитися більше NUMA‑вузлів.
Чому SRE мають піклуватися
Рішення щодо топології виявляються як:
- дрейф p95/p99 латентності коли ядро або планувальник мігрує потоки між ядрами/NUMA‑вузлами.
- нерівномірне використання CPU (один NUMA‑вузол гарячий, інші простоюють), бо локальність пам’яті визначає ефективну пропускну здатність.
- схильність jitter зберігання коли IRQ потрапляють на зайняті ядра на «не тому» NUMA‑вузлі відносно PCIe‑пристрою.
Правило: якщо навантаження має спільний стан і вам важлива латентність, тримайте його в одному домені кешу або прийміть витрати і вимірюйте їх. Надія — це не план.
Пам’ять і I/O: пропускна здатність, латентність, PCIe і реальність зберігання
У продакшені CPU рідко «ламаться» від того, що вони занадто повільні. Вони «ламаються», коли чекають. Чекають на пам’ять. Чекають на блокування. Чекають на завершення I/O. Кожне покоління Zen змінює ці патерни очікування.
Пропускна здатність пам’яті: тихий прискорювач (і тихий обмежувач)
З ростом кількості ядер пропускна здатність на ядро може впасти, якщо канали пам’яті не зростають пропорційно або якщо ви недо‑заповнили DIMM. DDR5 у Zen 4 допомагає, але також спокушає людей ставити менше DIMM «бо ємність вистачає». Потім вам телефонують, коли компактації та паузи GC стають гіршими.
Латентність пам’яті: податок на промахи
Латентність формується швидкістю пам’яті, таймінгами, поведінкою контролера та тим, наскільки далеко ядро від пам’яті, приєднаної до відповідного NUMA‑вузла. Зміни кешу в Zen 3 зменшують, як часто ви платите цей податок для певних патернів. Zen 4 все ще може карати погана локальність — просто швидше.
PCIe: коли «більше ліній» ≠ «більше продуктивності»
PCIe 4 → PCIe 5 подвоює теоретичну пропускну здатність, і ви навряд чи отримаєте 2× у реальному житті, якщо решта стеку не встигне: прошивка NVMe, блок‑шар ядра, трансляція IOMMU, маршрутизація IRQ і доступність CPU для завершень. Інженери зберігання вчаться цьому рано: шина рідко є єдиною шиною.
Відчуття, специфічні для зберігання
- Вища потенційна IOPS означає, що витрати CPU на обробку переривань NVMe можуть стати вузьким місцем раніше.
- Потенціал швидшого відновлення/scrub реальний, але лише якщо потоки перевірки сум‑контрольних/стискування і пропускна здатність пам’яті не б’ються між собою.
- Зближення мережі і зберігання (швидкі NIC + швидкі SSD) загнати вас в територію «вирівнювання IRQ і NUMA», хочете ви того чи ні.
Жарт №2: PCIe 5 чудовий — тепер ви можете переносити дані вдвічі швидше туди, де ваш додаток чекає на м’ютекс.
Віртуалізація і планувальники: секція «чому ця VM відчуває уповільнення?»
Еволюція платформи Zen змінює історію віртуалізації двома шляхами: топологією і мітгаціями. Гіпервізори і ядра стали кращими, ніж раніше, але вони все ще роблять дурниці, якщо ви не поясните, що таке «біля».
Розміщення VM і vNUMA: наближати обман до правди
Якщо VM думає, що має рівномірний доступ до пам’яті, а хост — мульти‑NUMA топологію, ви фактично просите гостя приймати погані рішення планування на великій швидкості. Pinning і vNUMA — це не «мікро‑оптимізації». Це спосіб зупинити трафік між вузлами пам’яті, який з’їдає вас.
Мітгації і мікрокод: порівняння продуктивності потребує контексту
Мітгації ядра можуть змінюватися між релізами ОС, і оновлення мікрокоду можуть змінювати поведінку. Коли хтось каже: «Zen 4 лише на 10% швидший за Zen 3 для нашого навантаження», ваше перше питання має бути: «Що змінилось у ядрі і прошивці, і ми вимірюємо те саме?»
Практичні завдання: команди, виводи, рішення (12+)
Ось частина, яку можна скопіювати у ваші ранбуки. Кожне завдання містить: команду, що означає її вивід, і рішення, яке з цього випливає. Це орієнтовано на Linux, бо більшість Zen‑серверів там живе.
Завдання 1: Визначити покоління CPU і stepping
cr0x@server:~$ lscpu | egrep 'Model name|CPU\(s\)|Socket|Thread|NUMA node\(s\)'
Model name: AMD EPYC 7B13 64-Core Processor
CPU(s): 128
Socket(s): 2
Thread(s) per core: 2
NUMA node(s): 8
Значення: Ви бачите рядок моделі (допомагає зіставити з поколінням Zen) і кількість NUMA‑вузлів (великий натяк на топологію).
Рішення: Якщо NUMA‑вузлів багато — плануйте роботу з розміщенням/прив’язкою, перш ніж звинувачувати додаток.
Завдання 2: Підтвердити NUMA‑топологію і відповідність CPU→вузол
cr0x@server:~$ numactl --hardware
available: 8 nodes (0-7)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 64412 MB
node 0 free: 51230 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 64500 MB
node 1 free: 52110 MB
...
Значення: Які ядра належать якому NUMA‑вузлу і скільки пам’яті доступно в кожному вузлі.
Рішення: Для латентнісно‑чутливих сервісів зафіксуйте CPU і пам’ять до вузла, який має локальний доступ до NIC/NVMe.
Завдання 3: Перевірити швидкість пам’яті і заповнені канали (швидкий сигнал)
cr0x@server:~$ sudo dmidecode -t memory | egrep 'Locator:|Speed:|Configured Memory Speed:|Size:'
Locator: P0_DIMM_A1
Size: 32 GB
Speed: 4800 MT/s
Configured Memory Speed: 4800 MT/s
Locator: P0_DIMM_B1
Size: 32 GB
Speed: 4800 MT/s
Configured Memory Speed: 4800 MT/s
Значення: Чи працюєте ви на очікуваних швидкостях і чи встановлені DIMM.
Рішення: Якщо конфігурована швидкість нижча за очікувану — виправте налаштування BIOS або розміщення DIMM перед тим, як тюнити софт.
Завдання 4: Побачити, чи CPU‑bound ви, чи чекаєте на I/O
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0 (server) 01/10/2026 _x86_64_ (128 CPU)
12:10:01 AM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
12:10:02 AM all 62.11 0.00 8.40 0.25 0.10 1.20 0.00 27.94
12:10:02 AM 0 95.00 0.00 3.00 0.00 0.00 0.00 0.00 2.00
...
Значення: Високе %usr означає роботу CPU; високе %iowait — CPU чекає на I/O.
Рішення: Якщо iowait високий — припиніть «тюнити CPU» і перевірте сховище/мережу. Якщо одне CPU задіяне на 100% — підозрюйте irq affinity або один «гарячий» потік.
Завдання 5: Виявити тиск у черзі виконання (перенавантаження планувальника)
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
12 0 0 5210432 91232 1832448 0 0 12 144 9800 21000 71 9 20 0 0
18 0 0 5209120 91232 1832600 0 0 0 512 9950 24000 76 10 14 0 0
Значення: r — кількість runnable‑задач. Коли вона постійно вища за доступні ядра (або за групу ядер, яка вам важлива), ви переповнені.
Рішення: Якщо черга виконання висока і латентність погана — зменшіть консолідацію або зафіксуйте критичні навантаження подалі від шумних сусідів.
Завдання 6: Перевірити поведінку частоти і тротлінг
cr0x@server:~$ lscpu | egrep 'CPU max MHz|CPU MHz'
CPU MHz: 2890.123
CPU max MHz: 3650.0000
Значення: Поточна частота vs макс.
Рішення: Якщо CPU MHz значно нижчий під навантаженням — перевірте power caps і thermal throttling у BIOS/BMC; не витрачайте час на «оптимізацію коду» спочатку.
Завдання 7: Підтвердити політику cpufreq governor
cr0x@server:~$ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
performance
Значення: Governor впливає на підйом частоти і усталене поведение.
Рішення: Для низьколатентних сервісів віддавайте перевагу performance (або настроєним профілям), якщо обмеження по енергії не виміряні й не явні.
Завдання 8: Перевірити поведінку NUMA‑балансування ядра
cr0x@server:~$ cat /proc/sys/kernel/numa_balancing
1
Значення: Автоматичне NUMA‑балансування може мігрувати пам’ять/сторінки для локальності, іноді викликаючи латентнісні джиттери.
Рішення: Якщо бачите періодичні стрибки латентності, що узгоджуються з міграціями — розгляньте відключення для зафіксованих робочих навантажень, але тестуйте — не копіюйте механічно.
Завдання 9: Перевірити фактичну локальність пам’яті процесу
cr0x@server:~$ pidof myservice
24819
cr0x@server:~$ numastat -p 24819
Per-node process memory usage (in MBs) for PID 24819 (myservice)
Node 0 Node 1 Node 2 Node 3 Node 4 Node 5 Node 6 Node 7 Total
----- ----- ----- ----- ----- ----- ----- ----- -----
Anon 812.3 19.5 3.1 0.2 0.1 0.0 0.0 0.0 835.2
File 42.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 43.0
Значення: Більшість пам’яті на Node 0, з невеликими віддаленими виділеннями в інших вузлах.
Рішення: Якщо пам’ять розпорошена по вузлах — зафіксуйте numactl або systemd CPUAffinity/NUMAPolicy для передбачуваної латентності.
Завдання 10: Перевірити локальність PCIe‑пристрою (який NUMA‑вузол володіє пристроєм)
cr0x@server:~$ lspci -nn | egrep 'Non-Volatile|Ethernet'
41:00.0 Non-Volatile memory controller [0108]: Samsung Electronics Co Ltd NVMe SSD Controller [144d:a808]
c1:00.0 Ethernet controller [0200]: Mellanox Technologies MT28908 Family [ConnectX-6] [15b3:101b]
cr0x@server:~$ cat /sys/bus/pci/devices/0000:41:00.0/numa_node
2
cr0x@server:~$ cat /sys/bus/pci/devices/0000:c1:00.0/numa_node
6
Значення: NVMe ближче до NUMA‑вузла 2; NIC — до вузла 6.
Рішення: Розміщуйте потоки зберігання біля вузла 2, мережеві потоки — біля вузла 6, або прийміть штраф між‑fabric і виміряйте його.
Завдання 11: Перевірити розподіл IRQ (поширена проблема Zen «чому одне ядро плавиться?»)
cr0x@server:~$ grep -E 'nvme|mlx|eth' /proc/interrupts | head
180: 9812234 0 0 0 PCI-MSI 524288-edge nvme0q0
181: 0 0 0 0 PCI-MSI 524289-edge nvme0q1
190: 5021132 0 0 0 PCI-MSI 532480-edge mlx5_comp0
Значення: Якщо всі переривання потрапляють на CPU0 (перший стовпець) — це поганий знак, якщо ви не спеціально закріпили таке.
Рішення: Якщо переривання сконцентровані — увімкніть і відтонюйте irqbalance або вручну призначте IRQ на CPU, що локальні до NUMA‑вузла пристрою.
Завдання 12: Підтвердити чергу NVMe і поведінку латентності
cr0x@server:~$ iostat -x 1 3
Linux 6.5.0 (server) 01/10/2026 _x86_64_ (128 CPU)
Device r/s w/s rMB/s wMB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz %util
nvme0n1 2200.0 1800.0 350.0 280.0 0.0 0.0 0.00 0.00 0.40 0.55 2.10 78.00
Значення: await — латентність; aqu-sz показує глибину черги; %util — насичення.
Рішення: Якщо %util близький до 100 і await росте — сховище насичене. Якщо await низький, але додаток повільний — підозрюйте CPU/блокування/мережу.
Завдання 13: Подивитися, чи обмежує вас пропускна здатність пам’яті (швидко і грубо)
cr0x@server:~$ perf stat -a -e cycles,instructions,cache-misses,LLC-load-misses,task-clock -- sleep 5
Performance counter stats for 'system wide':
98,234,112,991 cycles
73,120,443,210 instructions # 0.74 insn per cycle
1,223,110,992 cache-misses
401,223,114 LLC-load-misses
5,002.12 msec task-clock
5.000891981 seconds time elapsed
Значення: Низький IPC разом з великою кількістю LLC‑промахів часто вказує на затримки пам’яті (не завжди, але це сильний натяк).
Рішення: Якщо домінують затримки пам’яті — робіть локальність кеша пріоритетом, зменшуйте віддалений доступ до пам’яті і перевіряйте заповнення/швидкість DIMM перед тим, як ганятися за флагами компілятора.
Завдання 14: Перевірити міграції CPU (підказка про латентнісні джиттери)
cr0x@server:~$ perf stat -p 24819 -e context-switches,cpu-migrations -a -- sleep 10
Performance counter stats for 'system wide':
210,554 context-switches
12,321 cpu-migrations
10.004112343 seconds time elapsed
Значення: Висока кількість CPU‑міграцій може означати, що ваші потоки стрибають між ядрами/NUMA‑вузлами.
Рішення: Якщо p99 поганий і міграцій багато — розгляньте CPU affinity, cgroup cpusets або тюнінг планувальника. Не просто «збільшувати кількість реплік».
Завдання 15: Перевірити статус hugepages (важливо для VM і БД)
cr0x@server:~$ grep -E 'HugePages|Hugepagesize' /proc/meminfo
HugePages_Total: 8192
HugePages_Free: 7901
Hugepagesize: 2048 kB
Значення: Hugepages налаштовані і доступні.
Рішення: Якщо ви покладаєтесь на hugepages і вони вичерпуються — отримаєте стрибкоподібні латентності і тиск на TLB; відкоригуйте виділення або усуньте витік/фрагментацію.
Завдання 16: Перевірити KVM і прапори nested virtualization (хости хмари/VM)
cr0x@server:~$ lsmod | grep kvm
kvm_amd 155648 0
kvm 1064960 1 kvm_amd
cr0x@server:~$ cat /sys/module/kvm_amd/parameters/nested
0
Значення: Чи ввімкнена nested virtualization на хості.
Рішення: Увімкнюйте лише якщо потрібно. Nested ускладнює продуктивність і відладку; «на всяк випадок» — це як збирати загадкові оверхеди.
Плейбук швидкої діагностики: швидко знайти вузьке місце
Це послідовність триажу, якою я користуюсь, коли хтось каже: «Ми оновились з Zen X до Zen Y і не стало швидше» або «Швидше, але латентність погіршилась». Не імпровізуйте. Запускайте плей.
Перше: підтвердити реальність платформи (5 хвилин)
- CPU + кількість NUMA (
lscpu): чи на тій ви залізі, яку думаєте? Чи змінились налаштування BIOS і показник NUMA? - Швидкість і наповнення пам’яті (
dmidecode): чи працюєте ви на очікуваних MT/s? Чи неповні канали? - Governor і частота (
scaling_governor,lscpu): чи застрягли ви в політиці енергозбереження?
Друге: класифікувати вузьке місце (10 хвилин)
- CPU vs iowait (
mpstat): високе user/system vs високе iowait. - Тиск черги виконання (
vmstat): чи переповнені ви? - Підказка про затримки пам’яті (
perf stat): низький IPC + багато LLC‑промахів вказує на пам’ять.
Третє: вирівнювання топології (15–30 хвилин)
- Локальність пам’яті процесу (
numastat -p): чи процес здебільшого локальний? - NUMA‑вузол пристрою (
/sys/bus/pci/.../numa_node): чи NVMe/NIC поруч з ядрами, що виконують роботу? - Розподіл переривань (
/proc/interrupts): чи IRQ «плавлять» одне ядро?
Умова зупинки: коли ви знайдете клас вузького місця (CPU, пам’ять, I/O, топологія), припиняйте збирати випадкові метрики. Виконайте одну зміну, виміряйте і тільки потім рухайтесь далі.
Три корпоративні міні-історії (анонімізовані, правдоподібні і трішки болючі)
Міні‑історія 1: Інцидент від неправильної припущення
Компанія мігрувала флот API‑серверів з Zen 2 на Zen 4. Тести продуктивності були чудові: пропускна здатність зросла, середня латентність впала. Роллаут провели поступово. Через тиждень — інцидент: p99 стрибає кожні кілька хвилин, лише на новому флоті, лише під змішаним трафіком.
Он‑кол команда робила те, що робить кожен під тиском: дивилися на завантаження CPU. Воно було в нормі. Дивилися на GC — все добре. Дивилися на балансувальник навантаження — теж здавалось нормальним, мабуть, з приводу гордості.
Неправильне припущення було тонким: «NUMA тепер обробляється ядром». На старих хостах NIC і найзавантаженіші робочі потоки випадково були на одному NUMA‑вузлі через те, як шасі було підключено. На нових хостах NIC опинився на іншому вузлі. Сервіс був налаштований з CPU‑набором, що прив’язував воркерів до «перших» ядер — зручно, стабільно і тепер дуже далеко від NIC.
Кожен пакет робив зайву поїздку через fabric. При невеликому навантаженні це не грало ролі. Під навантаженням додаткова латентність і промахи кеша перетворилися на періодичну прірву, бо зайнятий вузол ставав ще завантаженішим і ядро починало мігрувати речі, щоб впоратися.
Виправлення було нудним: вирівняти CPU affinity воркерів з NUMA‑вузлом NIC і переконатися, що політика пам’яті відповідає. Стрибки зникли миттєво. Ніхто не хотів визнавати, що це «лише» топологія, але графіки не переймалися гордістю.
Міні‑історія 2: Оптимізація, що відбилася назад
Команда зберігання оновила метадані‑сервера з Zen 3 на Zen 4. Побачивши запас ресурсів, інженер підвищив паралельність: більше воркерів, глибші черги, більші батчі. Ідея — «використати всі ті ядра». Це спрацювало — поки не перестало.
Першим симптомом не була продуктивність; це була змінна поведінка. Латентність стала більш стрибкоподібною, а не просто повільнішою в середньому. Нічні роботи почали перекриватися з денними піками по‑іншому, ніж раніше. У очевидних метриках нічого не було «на максимумі».
Відбій — класичний: нова паралельність пересунула навантаження з CPU‑bound у memory‑bandwidth‑bound. Zen 4 змістив стелю, але патерн доступу навантаження — багато pointer chasing, багато промахів кеша — означав, що CPU в основному чекав. Додаткові потоки посилили конкуренцію і мелену кешу, і система витрачала більше часу на координацію ніж на корисну роботу.
Вони відкотили зміну паралельності й протестували. Пропускна здатність трохи впала, але p99 стабілізувався і перекриття технічного обслуговування перестало викликати видимі клієнтам болі. Потім зробили реальне виправлення: більш осмислене шардування «гарячих» метаданих і фіксація найбалакучіших потоків у щільнішу локальність.
Урок: більше ядер не означає, що слід сліпо підвищувати паралельність. Легко створити швидший вузький горлечко і назвати це апгрейдом.
Міні‑історія 3: Нудна але правильна практика, що врятувала ситуацію
Платформна команда мала звичку, яку інші команди дражнили: кожне нове покоління апаратури проходило через один і той самий чекліст приймання. Версія BIOS, рівень мікрокоду, версія ядра, політика governor, налаштування IOMMU і невеликий набір відтворюваних «smoke benchmarks». Це не було ефектним. За це не аплодували.
Під час rollout Zen 4 вони помітили невелику, але послідовну аномалію: один пакет вузлів мав нижчу стійну частоту під навантаженням і гірший p99 у smoke‑тестах. Не катастрофа. Просто «трохи не так». Різниця корелювала зі слабко відмінним BIOS‑профілем, що йшов з постачальника для того пулу.
Вони призупинили rollout тільки для тих вузлів, виправили BIOS‑профіль і відновили. За два тижні інша команда виявила, що їхні вузли тротлять під пиковими батч‑роботами — бо вони не стандартизували прошивки і вважали дефолти прийнятними.
Платформна команда не виглядала героїчно в моменті. Але й не мала аварії. Їхня практика була нудною — і в цьому суть.
Поширені помилки: симптоми → корінь → виправлення
Це секція, яку ви вставляєте в ticket інциденту. Конкретні симптоми, ймовірні корені і виправлення, що реально змінюють результат.
1) Симптом: p99 гірший після оновлення, середня латентність краща
Корінь: невідповідність топології (потоки далеко від NIC/NVMe), збільшені міграції CPU або побічні ефекти NUMA‑балансування на системі з великою кількістю ядер.
Виправлення: Перевірте NUMA‑вузол пристрою і зафіксуйте потоки сервісу відповідно; перевірте локальність пам’яті за допомогою numastat; зменште міграції за допомогою affinity/cpuset; розгляньте відключення NUMA‑балансування для зафіксованих сервісів.
2) Симптом: NVMe‑бенчмарки покращились, але I/O додатка — ні
Корінь: додаток CPU‑bound у обробці syscall/interrupt/completion; IRQ зосереджені на одному ядрі; накладні витрати IOMMU/remapping; неоптимальні налаштування черг.
Виправлення: Перевірте /proc/interrupts; розподіліть IRQ; налаштуйте черги; виміряйте використання CPU у softirq; зафіксуйте I/O‑потоки локально до пристрою.
3) Симптом: Одне ядро загіповано на 100% sys, інші простіють
Корінь: IRQ affinity прив’язана до одного CPU (або irqbalance вимкнено), або є один гарячий ядровий потік.
Виправлення: Увімкніть irqbalance або вручну встановіть IRQ affinity; перевірте через /proc/interrupts і знову перевірте під навантаженням.
4) Симптом: Пропускна здатність масштабується до N потоків, а потім застопорюється
Корінь: насичення пропускної здатності пам’яті, контенція за блокуваннями або домінування трафіку між NUMA‑вузлами.
Виправлення: Використовуйте perf stat для пошуку stall‑ів; зменшіть віддалений доступ до пам’яті; шардуйте блокування; застосуйте структури даних дружні до кеша; не додавайте потоки лише так.
5) Симптом: «Нові CPU повільніші» на хості VM
Корінь: oversubscription vCPU, неправильний vNUMA, мітгації включені інакше, або зміни політики живлення хоста.
Виправлення: Перевірте чергу виконання і steal time; вирівняйте vNUMA з фізичною топологією; забезпечте узгоджені політики ядра/мікрокоду; встановіть governor.
6) Симптом: Відновлення/rebuild/scrub повільніше на нових вузлах
Корінь: потоки контрольних сум/стискування плануються далеко від дисків; контенція за пропускною здатністю пам’яті з сусідніми сервісами; неповне заповнення каналів пам’яті.
Виправлення: Розміщуйте воркери зберігання біля NVMe‑NUMA‑вузла; резервуйте ядра; правильно заповніть канали пам’яті; виміряйте пропускну здатність і stall‑и CPU.
7) Симптом: Випадкові стрибки латентності кожні кілька хвилин
Корінь: фонові роботи ядра (міграції NUMA‑сторінок, kswapd), осциляції thermal/power limit або періодичні роботи технічного обслуговування, що тепер конфліктують через інші характеристики продуктивності.
Виправлення: Корелюйте стрибки з міграціями (perf migrations, зміни numastat), перевірте частоти і тротлінг, перенесіть технічне обслуговування і ізолюйте навантаження.
Чеклісти / покроковий план
Чекліст планування оновлення (до покупки або перерозподілу флоту)
- Класифікуйте навантаження: шар латентності проти шару пропускної здатності. Розміщуйте їх на відповідних SKU (щільно‑ядерні частини не чарівні для одиничної‑поточної латентності).
- Інвентаризуйте вузькі місця сьогодні: CPU, пропускна здатність пам’яті, латентність пам’яті, I/O або контенція за блокуваннями. Спочатку використайте плейбук «Швидка діагностика».
- Визначте, що означає «краще»: p99, пропускна здатність при фіксованому p99, ват/запит, час відновлення, коефіцієнт консолідації. Оберіть два, не сім.
- Сплануйте управління прошивкою: версія BIOS/AGESA, політика мікрокоду, версія ядра. Ставте це як зафіксовані залежності з контрольованим rollout.
- Розробіть NUMA‑політику: будете pin‑ити? Використовувати cpusets? Дозволите планувальнику гуляти? Прийміть рішення свідомо.
- Підтвердьте правила наповнення пам’яті: канали заповнені для пропускної здатності, не лише для ємності.
- Змапте локальність пристроїв: де підключені NIC і NVMe? Переконайтесь, що шасі відповідає моделі розміщення навантажень.
Чекліст приймання (перший рік нової генерації)
- Запустіть
lscpuі зафіксуйте модель CPU, NUMA‑вузли, max MHz. - Запустіть
dmidecodeі підтвердьте, що конфігурована швидкість пам’яті відповідає очікуванням. - Підтвердьте governor:
performance(або вашу обрану політику). - Перевірте розподіл IRQ під синтетичним навантаженням; виправте, якщо концентровано.
- Запустіть невеликий canary на рівні сервісу і порівняйте p50/p99, а не лише пропускну здатність.
- Запустіть smoke‑тести з мережі/зберігання і переконайтесь, що NUMA‑вузол пристрою відповідає стратегії розміщення потоків.
Операційний чекліст (поточний)
- Стандартизувати BIOS‑профілі і перевіряти відхилення.
- Відстежувати зміни ядра і мікрокоду як частину базових ліній продуктивності.
- Алертити про аномалії частот (тривалі годинникові частоти нижче очікуваних під навантаженням).
- Алертити про IRQ‑хотспоти (одне CPU отримує непропорційно багато переривань).
- Переглядати тиск консолідації: черги виконання, steal time і ефекти шумних сусідів.
Питання та відповіді
1) Чи є Zen 3 «великим» поколінням для латентнісно‑чутливих додатків?
Часто так — через зміну доменів кешу (єдиний L3 на CCD), що зменшує певні між‑ядерні штрафи. Але реальна відповідь залежить від того, скільки ваш додаток ділить дані між потоками і наскільки він чутливий до промахів кеша.
2) Чому мій p99 погіршився після переходу на новий CPU?
Тому що ви змінили топологію і поведінку, а не лише швидкість. Поширені причини: потоки тепер працюють далеко від NIC/NVMe; збільшились міграції CPU; NUMA‑балансування почало переміщувати сторінки; або ви потрапили в нове вузьке місце (пропускна здатність пам’яті, обробка IRQ).
3) Чи потрібно фіксувати процеси на сучасних системах Zen?
Якщо вам важлива передбачувана латентність — так, принаймні для критичних компонентів. Для пакетних/пропускних задач можна часто покластися на планувальник. Змішування обох без фіксації — це шлях до «швидко в середньому, жахливо, коли важливо».
4) Чи DDR5 завжди дає виграш?
Не автоматично. Вона підвищує стелі пропускної здатності, але латентність і конфігурація мають значення. Недозаповнені канали можуть стерти вигоду. Вимірюйте своїм навантаженням, а не надією.
5) Як зрозуміти, що я memory‑bound після апгрейду Zen?
Шукайте низький IPC із великою кількістю LLC‑промахів (perf stat) і масштабування, що перестає покращуватись при додаванні потоків. Потім підтвердьте, що пам’ять локальна (numastat) і що канали/швидкості DIMM налаштовані правильно.
6) Яка найпоширеніша «прихована» проблема на вузлах зберігання на нових поколіннях Zen?
Локальність переривань і розміщення CPU відносно NVMe. Залізо досить швидке, і помилки маршрутизації IRQ стають вузьким місцем.
7) Чи варто відключити NUMA‑балансування?
Для зафіксованих, латентнісно‑чутливих сервісів це може зменшити джиттер. Для загального багатокористувацького середовища воно може підвищити загальну ефективність. Правильна відповідь: протестуйте на вашому робочому навантаженні і порівняйте p99, а не лише середнє.
8) Чи змінюють покоління Zen поведінку ZFS?
ZFS залежить від CPU для контрольних сум і стиснення, від пропускної здатності пам’яті для ARC і навантажень з великою метаданою, і від I/O для латентності vdev. Нові Zen можуть прискорити CPU‑частину, але також роблять локальність IRQ і конфігурацію пам’яті важливішими.
9) Який практичний спосіб чесно порівняти покоління Zen?
Зафіксуйте: версію ядра, політику мітгацій, налаштування BIOS, заповнення/швидкості пам’яті, розміщення пристроїв і версію навантаження. Потім порівняйте при фіксованому p99 або при фіксованій пропускній здатності — не допускайте, щоб метрика сама змінилася.
Висновок: наступні кроки, які ви справді можете зробити
Еволюція Zen реальна, і ви її відчуваєте — але не завжди там, де вказує паспорт. Zen 3 зробив багато проблем латентності менш драматичними, змінивши домени кешу. Zen 4 зсунув стелю платформи завдяки DDR5 і PCIe 5, що означає: ваші старі «достатньо хороші» звички щодо I/O і топології тепер можуть стати вузьким місцем.
Наступні кроки, що швидко окуповуються:
- Запустіть плейбук «Швидка діагностика» на одному репрезентативному вузлі для кожного покоління. Не вгадуйте.
- Змапте локальність пристроїв (NIC/NVMe → NUMA‑вузол) і вирівняйте критичні потоки відповідно.
- Аудитуйте конфігурацію пам’яті: заповнені канали і конфігуровані швидкості, а не лише загальний об’єм GB.
- Перевірте розподіл IRQ під навантаженням і виправте хотспоти до того, як це стане «таємничим насиченням CPU».
- Стандартизувати прошивки і базові лінії ядра для флоту і відноситись до дрейфу як до ризику для продакшну.
Якщо ви зробите ці п’ять речей, оновлення Zen перестане бути стрибком віри і стане тим, чим має бути: інженерною зміною, яку можна осмислити, виміряти і розгорнути без сюрпризів.