Інцидентний тикет завжди читається однаково: «p99 затримка подвоїлася після оновлення; завантаження CPU нижче, ніж раніше; нічого не вкладається в голову.»
Після входу на новий флот ви виявляєте, що «CPU» вже не є одною річчю. Це маленьке місто: кілька кристалів, кілька контролерів пам’яті,
кілька рівнів кешу та інтерконект, що виконує рух у годину пік між ними.
Чіплети не просто змінили спосіб побудови процесорів. Вони змінили те, що означає «той самий модел процесора» в продакшені. Якщо ви купуєте, плануєте та налаштовуєте, як у 2012 році,
вас чекатимуть сюрпризи рівня 2012 — просто швидші й дорожчі.
Чому процесори стали як LEGO
«Монолітний» колись був компліментом. Один кристал, один корпус, одна ієрархія кешу, один набір правил.
Можна було уявляти кремній як плоску площину, де будь-яке ядро може дістатися до будь-якого байта пам’яті приблизно з однаковою вартістю.
Така вигадка померла з тих самих причин, з яких вмирають більшість елегантних теорій: гроші, фізика та планування.
Чіплетний процесор складається з кількох менших кристалів (чіплетів), зібраних в одному корпусі.
Деякі чіплети містять ядра та кеші. Інші можуть містити контролери пам’яті та I/O (PCIe, USB, SATA, CXL).
Чіплети розмовляють через on-package інтерконект.
Результат — модульність: постачальники можуть комбінувати блоки замість того, щоб проектувати один величезний, крихкий шматок кремнію.
Думайте про чіплети не як про «кілька CPU, схованих під плащем», а як про мініатюрну материнську плату з підсистемами, стиснуту в один корпус.
Ви отримуєте масштаб і гнучкість, але також отримуєте топологію. А топологія — це місце, куди продуктивність може піти або щоб вражати, або щоб породити тикети.
Цікаві факти та історичний контекст (те, що пояснює сьогоднішній безлад)
- Великі дієти мають жорстку криву виходу. Зі зростанням площі кристала ймовірність того, що дефект зіпсує кристал, зростає; чіплети тримають дієти меншими й підвищують вихід придатних кристалів.
- Модулі з кількома кристалами — не новинка. Упакування кількох кристалів в один модуль існує десятиліттями, але сучасна пропускна здатність інтерконектів зробила це мейнстрімом.
- «Клейка логіка» стала функцією. Ранні підходи з багатьма кристалами сприймалися як компроміси; сьогодні постачальники свідомо проектують під це.
- Контролери пам’яті перемістилися на кристал у 2000-х. Це зменшило затримки, але також підготувало ґрунт для NUMA і складності топології на сокеті.
- 2.5D упаковка (силіконові інтерпозери) змінила гру. Вона дозволила високошвидкісні лінії між кристалами без традиційних штрафів на рівні PCB.
- HBM зробив мислення в термінах чіплетів звичним. Стекована High Bandwidth Memory на пакеті підштовхнула всіх рахувати упаковку як частину архітектури.
- Чіплети дозволяють змішувати норми процесу. Ядра CPU можуть бути на передовому вузлі, а I/O — на зрілому вузлі, що дешевший і частіше краще підходить для аналогових блоків.
- Є стандартизаційні зусилля, але реальність є брудною. Індустрія хоче сумісних чіплетів; постачальники все ще спочатку випускають щільно інтегровані екосистеми.
Жарт №1: Якщо вам бракує простоти монолітних CPU, її досі можна знайти в природі — всередині одноклітинної істоти, також відомої як ваше стейджинг-середовище.
Чіплети на практиці: CCD, IOD, тайли та інтерконекти
Постачальники відрізняються брендингом, але патерн послідовний: відокремити високопродуктивні обчислювальні блоки від «комунікаційної» частини.
Обчислення люблять найновіший вузол процесу (швидкі транзистори, щільні кеші). I/O любить стабільні вузли (краща аналогія, висока напруга, дешевші пластини).
Типові блоки
- Обчислювальні чіплети: ядра CPU та їхні близькі кеші (L1/L2) плюс спільна частина кешу (часто L3).
- I/O die (IOD): контролери пам’яті, контролери PCIe/CXL, маршрутизатори fabric, іноді інтегровані акселератори.
- Інтерконект: on-package мережа, що дозволяє чіплетам ділитися пам’яттю та підтримувати когерентність кешу. Вона визначає ваші «локальні» та «віддалені» витрати.
- Субстрат пакета / інтерпозер: фізичне середовище для сигналів. Чим просунутіший, тим більше він може діяти як маленька високошвидкісна шина.
Що ви отримуєте
Ви отримуєте гнучкість виробництва. Якщо обчислювальний чіплет дефектний, ви викидаєте малий кристал, а не величезний моноліт.
Також можна зробити продуктовий стек, заповнивши корпус різною кількістю обчислювальних чіплетів — та сама I/O die, той самий сокет, різні SKU.
Що ви платите
Ви платите затримкою та «неуніформністю». Два ядра можуть мати ту саму мікроархітектуру, але бути на різній відстані від пам’яті.
Лінія кешу може жити в L3 шматку іншого чіплета. Потік може «перескочити» між чіплетами, якщо планувальник або ваша аплікація недбалі.
В термінах операцій: чіплети — машина для пропускної здатності, яка може перетворитися на машину хвостових затримок, якщо ви не поважаєте локальність.
Економіка: вихід придатних кристалів, бінування та чому великі дієти шкодять
Чіплети — це не передусім історія про продуктивність. Це бізнес-історія з наслідками для продуктивності.
Найбільший важіль у вартості напівпровідників — скільки хороших кристалів ви отримуєте з пласти.
Вартість пласта зростає з передовими вузлами; дефекти не підкоряються пропорціям.
Вихід, спрощено (без великого перебільшення)
На пласті є щільність дефектів. Кристал має площу. Більша площа збільшує ймовірність перетину критичного дефекту.
Ось чому великі монолітні кристали дорогі ще до пакування: ви викидаєте більше кремнію.
З чіплетами ви приймаєте, що деякі чіплети будуть погані, а деякі — хороші, і ви збираєте продукти з хороших.
Також можна бінувати чіплети за досяжною частотою або енергоспоживанням. Результат — ефективніше використання того, що виробляє фабрика.
Чому змішування вузлів процесу — практична інженерія, а не лише бухгалтерія
Передові вузли чудові для щільної логіки та кешів, але не автоматично кращі для будь-якої схеми.
PHY та аналогові блоки часто поводяться краще на зрілих вузлах. Також: на зрілих вузлах може бути краща доступність ланцюга постачання.
Коли I/O die залишається на зрілому вузлі, ви знижуєте ризик і можете продовжувати постачання навіть коли є обмеження на передовий процес.
Висновок для закупівель: «той самий сокет» більше не означає «та сама продуктивність». Два SKU можуть мати однакову назву та платформу,
але кількість чіплетів, схема кешу чи ревізія I/O die можуть змінити поведінку так, що ваші бенчмарки цього не вловлять, якщо ви не придивитеся.
Реалії продуктивності: затримка, пропускна здатність і топологія
Чіплети роблять пакет процесора більш схожим на невелику NUMA-систему, а не на однорідну плиту.
Навіть всередині одного сокета у вас можуть бути кілька доменів пам’яті, кілька островів L3 і інтерконект між ними.
Ваш вузький прохід часто не «CPU», а «CPU плюс де живуть дані».
Затримка: податок, який ви платите, коли дані «там»
Чутливість до затримки проявляється першою у p95/p99. Пропускні навантаження можуть приховувати це пакуванням і паралелізмом.
Інтерактивні сервіси — ні. Якщо шлях запиту зачіпає спільний стан з поганою локальністю, чіплети швидко виведуть цю вартість на поверхню.
Типові пастки затримки:
- Віддалений доступ до пам’яті: ядро завантажує дані з пам’яті, прикріпленої до іншого NUMA-вузла; це повільніше і може бути більш варіабельним.
- Трафік когерентності між чіплетами: false sharing та часті записи змушують інтерконект виконувати роботу, яку ви не врахували.
- Міграція потоків: планувальник переміщує ваш потік; його гарячий робочий набір більше не лежить у «ближніх» кешах.
Пропускна здатність: чіплети можуть бути величезними, але не безмежними
Загальний провал — вважати on-package fabric «майже таким же, як» монолітний кристал.
Він хороший, але не безкоштовний. Ви можете його наситити:
- Комунікації all-to-all (бар’єри, спільні черги, розподілені замки).
- Навантаження з інтенсивними копіюваннями пам’яті (серіалізація, стадії компресії, шифрування з поганим повторним використанням буферів).
- Високі числа ядер, які роблять одне і те саме до однієї області пам’яті.
Топологія кешу: L3 більше не є єдиним магічним резервуаром
Багато чіплетних дизайнів відкривають кілька L3-слайсів з швидшим локальним доступом і повільнішим віддаленим.
Ваша аплікація не бачить «L3 = 96MB» як одне однорідне озеро; вона бачить набір ставків, з’єднаних каналами.
Якщо ваш гарячий набір вміщується в одному ставку, але ви постійно гребете між ставками, ви все одно потонете.
Енергоспоживання та підвищення частоти: чіплети ускладнюють «чому сьогодні повільніше?»
Сучасні процесори жонглюють per-core boost, лімітами сокета, температурою і іноді обмеженнями по чіплетах.
Додавання чіплетів підвищує потенційну пікову пропускну здатність, але ви не завжди можете підвищити частоту всього одночасно.
Висновок для SRE: після оновлення «більше ядер» може означати «нижчий per-core turbo при тривалому навантаженні», що змінює затримку.
Цитата (парафраз): Werner Vogels: будуй системи, очікуючи на збої, і проектуй для стійкості замість припущення, що компоненти поводяться охайно.
Жарт №2: Чіплети — як мікросервіси: чудово, поки ви не зрозуміли, що винайшли мережу, і тепер дебагаєте її о 5 ранку.
Що змінюється для SRE та команд платформи
У монолітному світі часто можна було відбутися фразою «Linux відпланує це» і «база даних впорається».
У світі чіплетів, значення за замовчуванням непогане, але вони не відповідають вашому навантаженню.
Якщо вам важлива хвостова затримка, ви маєте активно керувати локальністю: прив’язка CPU, NUMA‑дружнє виділення пам’яті, IRQ affinity та розумні налаштування BIOS.
Що вимагати від постачальників і департаменту закупівель
- Повне розкриття топології: кількість NUMA‑вузлів на сокет, канали пам’яті на вузол, розклад кешу та клас пропускної здатності інтерконекту.
- Послідовне відображення SKU: якщо «дрібний» степпінг змінює I/O die або поведінку пам’яті, ви хочете реліз-ноти та час на валідацію.
- Поведение потужності під тривалим навантаженням: політики турбо важать більше, ніж базові частоти в специфікації.
Чого вимагати від власної організації
- Бенчмарки, що відповідають продакшену: синтетичні CPU‑бенчмарки — це розвага, а не доказ.
- Планування ємності з урахуванням топології: плануйте по NUMA‑вузлах, а не лише по сокетах.
- Стандарти щодо планування та прив’язки: оркестратори контейнерів потребують керівництва, а не надій на удачу.
Практичні завдання: команди, виводи, що це означає та що вирішуєте
Це перевірки рівня продакшену. Запустіть їх на хості з «таємничою регресією продуктивності».
Кожне завдання містить команду, типовий вивід, що означає вивід і рішення, яке ви приймаєте.
Завдання 1: Побачити CPU та NUMA топологію
cr0x@server:~$ lscpu
Architecture: x86_64
CPU(s): 64
Thread(s) per core: 2
Core(s) per socket: 32
Socket(s): 1
NUMA node(s): 4
NUMA node0 CPU(s): 0-15
NUMA node1 CPU(s): 16-31
NUMA node2 CPU(s): 32-47
NUMA node3 CPU(s): 48-63
L3 cache: 256 MiB
Значення: Один сокет, але чотири NUMA‑вузли. Це локальність у стилі чіплетів. Ваш «один сокет» поводиться як невеликий мультипроцесор.
Рішення: Ставтеся до цього хоста як до NUMA. Прив’язуйте сервіси, чутливі до затримки, до одного вузла і виділяйте пам’ять локально.
Завдання 2: Перевірити NUMA‑відстані (наскільки «далеко» насправді)
cr0x@server:~$ numactl --hardware
available: 4 nodes (0-3)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 64000 MB
node 0 free: 52210 MB
node distances:
node 0 1 2 3
0: 10 20 20 28
1: 20 10 28 20
2: 20 28 10 20
3: 28 20 20 10
Значення: Не всі віддалені вузли однакові. «28» помітно гірше за «20». Деякі чіплети розташовані далі один від одного.
Рішення: Для суворої затримки тримайте потоки та пам’ять у межах одного вузла; для розподіленої роботи віддавайте перевагу «ближчим» парам.
Завдання 3: Підтвердити, що ядро бачить правильну NUMA‑політику
cr0x@server:~$ cat /proc/sys/kernel/numa_balancing
1
Значення: Автоматичне балансування NUMA увімкнено. Воно може допомагати загальним навантаженням, але також може спричиняти міграції сторінок і стрибки затримки.
Рішення: Для сервісу з критичною латентністю розгляньте вимкнення на хості або в межах cgroup і керуйте афінністю вручну.
Завдання 4: Перевірити поведінку частот CPU (boost vs throttling)
cr0x@server:~$ sudo turbostat --Summary --quiet --show Busy%,Bzy_MHz,PkgWatt,PkgTmp
Busy% Bzy_MHz PkgWatt PkgTmp
72.18 3045 245.7 88
Значення: Під навантаженням ядра в середньому ≈3.0 GHz, потужність пакета висока, температура близька до граничних значень.
Рішення: Якщо p99 гірший за попереднє покоління, перевірте охолодження, обмеження потужності та налаштування BIOS перед тим, як звинувачувати код.
Завдання 5: Виявити тиск на пропускну здатність пам’яті
cr0x@server:~$ sudo perf stat -a -e cycles,instructions,cache-misses,LLC-load-misses,LLC-store-misses sleep 10
Performance counter stats for 'system wide':
38,220,118,992 cycles
52,908,331,407 instructions # 1.38 insn per cycle
1,182,220,114 cache-misses
992,110,332 LLC-load-misses
88,330,901 LLC-store-misses
10.001024001 seconds time elapsed
Значення: Висока кількість LLC miss вказує, що навантаження виходить за межі кешу і б’є по пам’яті (або по віддалених кеш-лініях).
Рішення: Дослідіть локальність: прив’язуйте потоки, зменшуйте крос‑потокове шарування та перевіряйте виділення пам’яті по NUMA‑вузлах.
Завдання 6: Виявити тиск планувальника та runqueue (чи стрибають потоки?)
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0 (server) 01/10/2026 _x86_64_ (64 CPU)
12:04:18 AM CPU %usr %sys %iowait %irq %soft %idle
12:04:19 AM all 58.12 9.44 0.05 0.10 0.65 31.64
12:04:19 AM 0 92.00 6.00 0.00 0.00 0.00 2.00
12:04:19 AM 16 12.00 18.00 0.00 0.00 1.00 69.00
12:04:19 AM 32 86.00 9.00 0.00 0.00 0.00 5.00
12:04:19 AM 48 14.00 22.00 0.00 0.00 2.00 60.00
Значення: Деякі CPU гарячі, інші недовантажені, а деякі показують підвищений системний час. Це може вказувати на дисбаланс IRQ або погане прив’язування.
Рішення: Перевірте IRQ affinity і впевніться, що ваші сервісні потоки прив’язані послідовно, щоб уникнути міграцій між чіплетами.
Завдання 7: Інспектувати розподіл IRQ (класична прихована пляшка)
cr0x@server:~$ cat /proc/interrupts | head
CPU0 CPU1 CPU2 CPU3
24: 98211233 0 0 0 PCI-MSI 524288-edge eth0-TxRx-0
25: 0 0 0 0 PCI-MSI 524289-edge eth0-TxRx-1
26: 0 0 0 0 PCI-MSI 524290-edge eth0-TxRx-2
27: 0 0 0 0 PCI-MSI 524291-edge eth0-TxRx-3
Значення: Один ядро обробляє майже всі інтеррапти NIC. Локальний чіплет цього ядра може випадково стати «мережевим чіплетом».
Рішення: Увімкніть irqbalance або встановіть явну афінність, щоб інтеррапти розподілялись по потрібних ядрах (і бажано в межах того самого NUMA‑вузла, що й NIC).
Завдання 8: Перевірити локальність пристроїв PCIe (який NUMA‑вузол має NIC/NVMe)
cr0x@server:~$ cat /sys/class/net/eth0/device/numa_node
2
Значення: NIC підключено до NUMA‑вузла 2. Якщо ваш мережевий стек працює на вузлі 0, ви виконуєте віддалені операції з пам’яттю та bookkeeping DMA.
Рішення: Прив’яжіть мережеві потоки до вузла 2 (або перемістіть IRQ) і виділяйте буфери на вузлі 2 де можливо.
Завдання 9: Підтвердити, що пам’ять дійсно локальна для сервісу
cr0x@server:~$ numastat -p 12345
Per-node process memory usage (in MB) for PID 12345 (myservice)
Node 0 1200.3
Node 1 980.1
Node 2 8200.7
Node 3 410.2
Total 10791.3
Значення: Процес переважно на вузлі 2, але має значні виділення на інших вузлах — потенційні крос‑вузлові звернення.
Рішення: Якщо сервіс чутливий до затримки, звужуйте прив’язку CPU і пам’яті (systemd, cgroups, taskset, numactl), щоб він не розповзався.
Завдання 10: Перевірити активність міграції сторінок (побічні ефекти балансування NUMA)
cr0x@server:~$ grep -E 'pgmigrate|numa' /proc/vmstat | head -n 10
pgmigrate_success 1822331
pgmigrate_fail 1122
numa_pte_updates 998122
numa_hint_faults 288111
numa_hint_faults_local 201994
numa_pages_migrated 155002
Значення: Ядро активно мігрує сторінки. Це може бути корисно для пропускної здатності, але додає джиттер і конкуренцію.
Рішення: Якщо ви бачите спайки хвостової затримки, спробуйте контролювати розміщення явно і зменшити залежність від автоматичної міграції.
Завдання 11: Перевірити стан huge pages (TLB‑тиск vs фрагментація)
cr0x@server:~$ grep -E 'HugePages|Hugepagesize' /proc/meminfo
HugePages_Total: 2048
HugePages_Free: 1980
HugePages_Rsvd: 12
Hugepagesize: 2048 kB
Значення: Huge pages доступні й переважно вільні; ваш сервіс може їх не використовувати або резервувати кілька.
Рішення: Для сервісів з інтенсивною пам’яттю перевірте, чи зменшують huge pages TLB misses; не вмикайте бездумно, якщо алокація розпорошена по NUMA‑вузлах.
Завдання 12: Перевірити CPU set у cgroup для контейнерного навантаження
cr0x@server:~$ systemctl show myservice --property=CPUQuota --property=AllowedCPUs --property=AllowedMemoryNodes
CPUQuota=400%
AllowedCPUs=0-31
AllowedMemoryNodes=0-1
Значення: Сервіс обмежено CPU 0–31 і вузлами пам’яті 0–1. Якщо NIC/NVMe знаходиться на вузлі 2, ви щойно збудували машину з віддаленим доступом.
Рішення: Узгодьте CPU та вузли пам’яті з локальністю пристрою. Розмістіть сервіс там, де знаходиться його I/O, або перемістіть пристрої/IRQ відповідно.
Завдання 13: Швидкий тест локальної vs віддаленої пам’яті (spot‑check)
cr0x@server:~$ sudo numactl --cpunodebind=0 --membind=0 bash -c 'dd if=/dev/zero of=/dev/null bs=1M count=4096'
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 0.642 s, 6.7 GB/s
cr0x@server:~$ sudo numactl --cpunodebind=0 --membind=3 bash -c 'dd if=/dev/zero of=/dev/null bs=1M count=4096'
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB, 4.0 GiB) copied, 0.811 s, 5.3 GB/s
Значення: Прив’язка до віддаленої пам’яті зменшує спостережувану пропускну здатність. Реальні аплікації платять також додатковою затримкою, не лише втратою пропускної здатності.
Рішення: Якщо віддалена прив’язка суттєво змінює числа, у вас чутливе до локальності навантаження. Трактуйте розміщення як вимогу першого класу.
Завдання 14: Переглянути підказки про кеш і топологію у sysfs
cr0x@server:~$ for c in 0 16 32 48; do echo "cpu$c:"; cat /sys/devices/system/cpu/cpu$c/cache/index3/shared_cpu_list; done
cpu0:
0-15
cpu16:
16-31
cpu32:
32-47
cpu48:
48-63
Значення: Кожна група з 16 CPU ділить L3 — чотири L3 «острови». Це межа кордону чіплета/кластеру кеша, яку слід поважати.
Рішення: Прив’язуйте взаємодіючі потоки в межах одного L3‑острова. Тримайте чатливі пулі потоків разом; відсаджуйте шумних сусідів на інші острови.
Швидкий план діагностики: знайдіть вузьке місце, перш ніж сперечатися про архітектуру
Коли сервіс регресує на CPU епохи чіплетів, найшвидший шлях — не глибока дискусія про мікроархітектуру.
Це дисциплінована тріаж: топологія, локальність, потужність, потім код.
Перше: підтвердьте, чим насправді є машина
- Топологія: запустіть
lscpuтаnumactl --hardware. Якщо NUMA‑вузлів > 1 на сокет, ставтеся до нього як до чутливого до топології. - Острови кешу: перевірте спільні групи L3 через sysfs (Завдання 14). Це часто прогнозує штрафи між чіплетами краще, ніж маркетингова назва.
- Локальність пристроїв: перевірте NIC/NVMe
numa_nodeу sysfs. Пристрої, прив’язані до одного вузла, можуть тягнути за собою все навантаження віддалено.
Друге: визначте, чи біль — це затримка, пропускна здатність чи планування
- Затримка / джиттер: погляньте на p95/p99 відносно середнього. Якщо середнє OK, а хвіст жахливий — підозрюйте міграції, віддалену пам’ять, дисбаланс IRQ або обмеження по потужності.
- Пропускна здатність: використайте
perf statдля LLC misses, слідкуйте за вибухом cache-miss під навантаженням. Також перевірте насичення каналів пам’яті з допомогою інструментів постачальника. - Планування: використайте
mpstat -P ALL. Гарячі та холодні ядра вказують на проблеми з прив’язкою, гарячі точки IRQ або нерівномірний розподіл роботи.
Третє: перевірте політику та розміщення
- NUMA балансування: перевірте
/proc/sys/kernel/numa_balancingта статистику міграцій у/proc/vmstat. - cgroups / cpusets: переконайтеся, що CPU та вузли пам’яті узгоджені з I/O сервісу.
- IRQ афінність: підтвердіть, що інтеррапти розподілені та локальні для вузла пристрою.
Четверте: лише після цього налаштовуйте або рефакторте
- Якщо проблема в локальності: прив’яжіть потоки, встановіть політику пам’яті, реструктуруйте алокації.
- Якщо проблема в пропускній здатності: зменшіть спільну активність стану, уникніть false sharing, зменшіть memcpy, пакуйте роботу, перегляньте стратегію компресії/шифрування.
- Якщо проблема в потужності: виправте охолодження, ліміти потужності та налаштування BIOS; не «оптимізуйте» код, щоб компенсувати теплову проблему.
Типові помилки (симптом → корінь → виправлення)
1) Симптом: p99 затримка погіршилася після оновлення CPU, але середня затримка покращилася
Корінь: Міграції між чіплетами та віддалені доступи до пам’яті спричиняють хвилі джиттера.
Виправлення: Прив’яжіть потоки обробки запитів в межах одного L3‑острова; прив’яжіть пам’ять до того ж NUMA‑вузла; зменшіть міграції потоків (афінність, менше runnable‑потоків, уникайте надмірно великих пулів).
2) Симптом: «CPU завантажений лише на 40%», але пропускна здатність швидко доходить до стелі
Корінь: Насичено пропускну здатність пам’яті або інтерконект; додаткові ядра не допомагають, якщо ви обмежені каналом.
Виправлення: Використайте perf stat для підтвердження cache misses; зменшіть копіювальні шляхи; профілюйте поведінку алокатора; підвищуйте локальність; розгляньте шарування по NUMA.
3) Симптом: мережево‑важкий сервіс показує одне ядро, завантажене на 100% системного часу
Корінь: IRQ affinity концентрує інтеррапти на одному CPU; пристрій знаходиться на іншому NUMA‑вузлі, ніж потоки сервісу.
Виправлення: Розподіліть IRQ по ядрах на NUMA‑вузлі пристрою; вирівняйте CPU set сервісу з тим же вузлом; перевірте через /proc/interrupts та sysfs.
4) Симптом: продуктивність сильно відрізняється між однаково виглядаючими хостами
Корінь: Налаштування BIOS відрізняються (обмеження потужності, інтерлів пам’яті, SMT, налаштування NUMA); відмінності степпінгу змінюють поведінку топології.
Виправлення: Стандартизуйте BIOS‑профілі; відстежуйте версії прошивки; валідуйте коротким topology/perf smoke‑тестом під час провізіонінгу.
5) Симптом: база даних гіршає при додаванні воркер‑потоків
Корінь: Конкуренція за замки та bouncing кеш‑ліній між чіплетами; false sharing у спільних чергах/лічильниках.
Виправлення: Обмежте потоки на L3‑острів; шардуйте гарячі дані по NUMA‑вузлах; використовуйте per‑core/per‑node лічильники з періодичною агрегацією.
6) Симптом: контейнерний сервіс «випадково» трясе пам’ять і стає в затримку
Корінь: cpuset дозволяє CPU на одному вузлі, але алокації пам’яті потрапляють на інші вузли через дефолти, міграції сторінок або спільні хости‑алокації.
Виправлення: Встановіть і CPU, і політики вузлів пам’яті в cgroups; перевірте через numastat -p; розгляньте вимкнення автоматичного NUMA‑балансування для цього навантаження.
Три корпоративні історії епохи чіплетів
Міні‑історія 1: Інцидент через хибне припущення
Платформна команда розгорнула новий «одно‑сокетний, високоядерний» сервер замість старих двохсокетних машин. Ідея була проста:
менше сокетів — менше проблем з NUMA, і чіп мав багато ядер. План міграції трактував кожен хост як однорідний пул CPU.
За тиждень один API, орієнтований на клієнтів, почав тайм‑аутитися епізодично. Це не було постійним перевантаженням — сплески.
Графіки дратували: завантаження CPU виглядало здоровим, рівень помилок підвищився, а додавання інстансів допомагало менш ніж очікувалось.
Он‑кол інженер зробив стандартні перевірки: GC, база даних, мережа.
Нічого очевидного.
Прорив прийшов з перевіркою топології. «Один сокет» виявив чотири NUMA‑вузли. NIC була на вузлі 2.
Оркестратор прив’язував поди до CPU 0–31 (вузли 0 і 1), бо це було дефолтним CPU set у образі хоста.
Мережеві інтеррапти також концентрувались на ядрі у вузлі 2. Система виконувала складний танець:
пакети приходили на вузол 2, оброблялися ядром IRQ на вузлі 2, ставили у чергу в пам’ять не завжди локальну,
потім воркер‑потоки на вузлах 0/1 діставали роботу віддалено. Крос‑вузловий трафік плюс планувальний джиттер вбили p99.
Виправлення було нудним: вирівняти cpusets та вузли пам’яті з локальністю NIC, рознести IRQ по вузлу та тримати потоки поруч з їхніми буферами.
Сервіс стабілізувався. Головний урок постмортеему теж був нудним: «одно сокет» — не синонім до «однорідної пам’яті». На чіплетних системах так ніколи не було.
Наступна дія, що має значення: команда додала ворота провізіонінгу, які відкидали хости, де NUMA‑вузол пристрою не відповідав передбаченому CPU‑сету.
Не гламурно, але запобігло повторенню.
Міні‑історія 2: Оптимізація, що повернулася бумерангом
Команда датапайплайну оптимізувала гарячий шлях, збільшивши паралелізм. Вони взяли batch‑джоб, який працював з 32 воркерами, і «масштабували» його
до 128 потоків на новому поколінні високоядерних чіплетних CPU. Міркування були канонічні: більше ядер — більше потоків — більше пропускної здатності.
Перший бенчмарк виглядав добре — короткочасно. У коротких прогонах пропускна здатність підвищувалась. У довгих — деградувала і ставала шумною.
Агрегована продуктивність кластера стала непослідовною, а час виконання джобу перестав покращуватись.
Інші сервіси на тих самих хостах почали скаржитись на затримку, хоча «це лише batch‑джоб».
Розбір показав, що корінь у тиску на інтерконект і пам’ять, а не у CPU‑насиченні. Навантаження мало спільну чергу і декілька глобальних лічильників, які часто оновлювались.
На монолітному кристалі це було дратівливо, але терпимо.
На топології з кількома L3‑островами це перетворилося на генератор когерентного трафіку.
Додайте міграції потоків — і отримаєте те, що передбачали лічильники perf: багато cache miss і крос‑вузлового гомону.
«Виправлення» полягало в зменшенні паралелізму, а не в його збільшенні. Вони обмежили потоки на L3‑острів і ввели per‑node черги та лічильники.
Джоб використовував менше потоків, але завершувався швидше і припинив «бити» по решті вузла.
Болісний урок: CPU епохи чіплетів карає за недбалу архітектуру спільного стану. Кидання потоків у проблему — не масштабування; це стратегія відмови.
Після цього команда змінила критерій оптимізації: будь‑яке покращення, що збільшує крос‑потокове шарування, має мати топологічно‑дружній бенчмарк,
інакше воно не йде в продакшен. Вони також перестали святкувати «зріст завантаження CPU» як перемогу. Використання — не те саме, що пропускна здатність, і тим більше не хвостова латентність.
Міні‑історія 3: Нудна, але правильна практика, що врятувала день
Інфраструктурна група керувала змішаним флотом: два покоління CPU, кілька версій BIOS і поступові оновлення прошивок.
Вони не були героями. Вони просто були організованими.
Кожний хост, що провізіонувався, проходив «burn‑in» пайплайн, який збирав топологію, локальність пристроїв і короткий набір лічильників під навантаженням.
Одного тижня вони помітили тонку зміну: частина нових хостів показувала вищі коефіцієнти віддалених доступів для того ж синтетичного тесту розміщення.
Машини не ламалися, і ніхто не звертався з тикетом. Пайплайн спіймав це, бо базовий набір включав NUMA‑відстані і мікробенчмарк, закріплений local vs remote.
Вином виявився дрейф BIOS‑профілю. Доброзичливий технік застосував vendor «performance» preset, що змінив поведінку інтерліву пам’яті.
Це не зламало машину; просто змінило характеристики локальності достатньо, щоб це стало помітно для сервісів з критичною латентністю.
Без burn‑in пайплайна це перетворилось би на «рандомні регресії» через тижні.
Вони відкотили профіль, перевстановили кілька хостів і продовжили роботу. Без інциденту, без екстрених зустрічей.
Практика, що врятувала їх, не була геніальною. Вона була послідовністю: ставте топологію і локальність в ряд конфігураційного дрейфу і тестуйте її, як тестуєте стан диска.
Чеклісти / покроковий план
Чекліст: як впровадити чіплетні CPU без створення жаху з латентністю
- Інвентаризація топології: зафіксуйте NUMA‑вузли на сокет, спільні групи L3, канали пам’яті та NUMA‑вузли пристроїв.
- Визначте класи навантажень: критичне за затримкою, пропускне, batch, шумні бекграунд‑процеси. Не все отримує однакові правила розміщення.
- Оберіть політику розміщення:
- Критичне за затримкою: прив’язка в межах одного L3‑острова і одного NUMA‑вузла.
- Пропускне: шардування по NUMA‑вузлах; масштабування по вузлах, якщо дані партиціонуються.
- Batch: ізоляція на конкретних вузлах/ядрах; обмеження «хвостів» пропускної здатності.
- Вирівняйте локальність I/O: розміщуйте мережево‑важкі або NVMe‑важкі сервіси на NUMA‑вузлі, прикріпленому до цих пристроїв.
- Стандартизуйте BIOS та прошивку: один профіль, відстежена версія, зміни проходять через канарки.
- Перевірте поведінку потужності: верифікуйте стійкі частоти під вашим реальним навантаженням, а не лише «воно трохи розженеться».
- Створіть smoke‑тест: запустіть local‑vs‑remote memory тест і короткий perf capture під час провізіонінгу.
- Навчіть ваш планувальник: закодуйте cpuset/mems політики у systemd unit‑ах або в мітках нодів оркестратора та pod‑спеках.
- Документуйте режими відмов: дисбаланс IRQ, віддалена пам’ять, контенція замків між вузлами, теплове тротлінг.
- Розгортайте з канарками: порівнюйте p99, а не лише пропускну здатність. Визначайте критерії відкату.
Покроково: виправлення регресії локальності на живому хості
- Запустіть
lscpuтаnumactl --hardware; запишіть вузли, діапазони CPU, відстані. - Знайдіть локальність пристроїв (NIC/NVMe) через sysfs
numa_node. - Перевірте розподіл IRQ (
/proc/interrupts) і виправте афінність, якщо одне ядро перевантажене. - Перевірте cpuset сервісу і політику вузлів пам’яті (властивості systemd або файли cgroup).
- Використайте
numastat -p, щоб підтвердити, що алокації пам’яті сервісу відповідають розміщенню CPU. - Вимкніть автоматичне NUMA‑балансування для цього сервісу, якщо воно викликає надто багато міграцій; повторно перевірте p99.
- Обмежте пул потоків так, щоб він вміщувався в один L3‑острів за можливості; уникайте крос‑острової контенції.
- Перезапустіть короткий навантажувальний тест і порівняйте p50/p95/p99 та perf‑лічильники.
FAQ
1) Чи чіплети завжди повільніші за монолітні процесори?
Ні. Чіплети часто дають кращу пропускну здатність, більше ядер, більший агрегований кеш і кращу економіку. Вони «повільні» лише тоді, коли ваше навантаження
платить податок за віддалені доступи та трафік когерентності, який ви не передбачили — зазвичай помітно у хвостових затримках.
2) Чому не зробити інтерконект настільки швидким, щоб це не мало значення?
Через фізику та енергію. Приведення високошвидкісних сигналів коштує енергії і генерує тепло. Також затримка вперта; пропускну здатність купити легше, ніж зменшити круговий час.
3) NUMA — це те саме, що чіплети?
Не те саме, але вони римуються. NUMA — це модель продуктивності: час доступу до пам’яті залежить від того, який контролер пам’яті володіє сторінкою.
Чіплети — це підхід пакування/архітектури, який часто створює кілька доменів пам’яті і островів кешу навіть в межах одного сокета.
4) Якщо Linux бачить один сокет, чому мені це має хвилювати?
Тому що «сокет» — це облікова мітка. Linux все одно може експонувати кілька NUMA‑вузлів і окремі групи спільного кешу.
Вашій аплікації важливо, де лежать сторінки пам’яті і які ядра ділять кеш, а не кількість фізичних сокетів.
5) Чи потрібно тепер прив’язувати все до CPU?
Не все. Прив’язка — інструмент, а не релігія. Використовуйте її для сервісів, чутливих до латентності, високопродуктивних мережевих стеків та всього, що потребує тісної локальності кешу.
Для загальних stateless‑навантажень дефолтне планування може бути прийнятним — поки ви не помітите дрейф p99.
6) Яка найбільша помилка команд під час оновлень?
Припускати, що новий CPU — це просто «старий CPU, але швидший». Чіплети змінюють топологію, поведінку кешу та динаміку потужності.
Якщо ви не вимірюєте локальність і стійкі частоти під вашим навантаженням, ви робите оновлення за відчуттями.
7) Більше L3 кешу означає менше проблем?
Більше кешу допомагає, але топологія має значення. Якщо кеш розділений на острови й ваші потоки стрибають між островами, ви все одно можете часто пропускати дані.
Використовуйте спільні групи L3 як межу для розміщення.
8) Як чіплети впливають на віртуалізацію та контейнери?
Вони підвищують вартість недбалого розміщення. VM та контейнери можуть отримати vCPU, розкидані по NUMA‑вузлах, в той час як їхня пам’ять лежить в інших місцях.
Вирішіть це політиками CPU і пам’яті (cpuset + mems) і валідуйте через numastat та перевірки топології.
9) Чи чіплети збільшують частоту відмов?
Не обов’язково. Вони змінюють місце ризику: складніше пакування й інтерконекти, але часто кращий вихід і бінування.
Операційно основна «відмова» — непередбачуваність продуктивності, а не явні апаратні збої.
10) Що треба бенчмаркувати, щоб порівняти два чіплетні CPU?
Прогоніть ваш робочий навантаження з реалістичною конкуренцією, реальними розмірами даних і реальним I/O. Фіксуйте p99, а не лише середнє.
Також знімайте топологію (NUMA‑відстані, спільність L3), щоб ви могли пояснити відмінності, а не сперечатися про них.
Наступні кроки, які реально зробити цього тижня
Чіплети — не мода. Це типовий шлях масштабування ядер та змішування вузлів процесу. Боротися з цим — як боротися з гравітацією:
можна на деякий час, але на інцидент‑колі ви не виглядатимете розумно.
- Додайте топологію до фактів хоста: зберігайте
lscpu,numactl --hardware, спільні групи L3 і NUMA‑вузли пристроїв у вашому інвентарі. - Зробіть розміщення явним: для одного критичного сервісу за латентністю реалізуйте прив’язку CPU і пам’яті та документуйте рішення.
- Аудит IRQ affinity на ваших найзавантаженіших хостах. Якщо одне ядро несе весь світ — виправте і отримайте простий виграш.
- Створіть smoke‑тест local vs remote під час провізіонінгу, щоб дрейф BIOS і дивні степпінги ловилися ще до продукції.
- Перепишіть один гарячий спільний вузол: замініть глобальний лічильник/чергу на per‑NUMA або per‑core шардування, потім виміряйте хвостову латентність.
Мета не стати архітектором CPU. Мета — перестати дивуватися фізиці, яку можна виміряти за 30 секунд.
Чіплетні CPU виглядають як LEGO, бо на виробництві й економіці це було необхідно. Ваше завдання — керувати ними як модульними, бо вони такими є.