Ваш GPU «завантажений на 95%», панель показує зелений статус, але клієнт все ще скаржиться на пропуски кадрів або стрибки латентності інференсу.
Ласкаво просимо в ту частину продакшену, де середні значення брешуть, а вузькі місця ховаються на видному місці.
ROPs, TMUs, SMs і CUs — це не дуже гучні назви частин, але саме вони вирішують, чи GPU бігає, кульгає або чекає на пам’ять, немов застряг за повільним навантажувачем.
Це карта, яку ви використовуєте, коли числа не складаються.
Ментальна модель, що витримує реальні навантаження
Існує два поширені режими відмов, коли люди говорять про «продуктивність GPU»:
(1) розглядати GPU як єдине число (utilization), і
(2) сприймати частини GPU як чарівні слова («більше SMs вирішить проблему»).
Обидва підходи ведуть до дорогих помилок.
Використовуйте цю ментальну модель натомість: GPU — це конвеєр спеціалізованих цехів зі спільними дорогами.
SMs/CUs — це місця, де відбувається більшість арифметики; TMUs спеціалізуються на вибірці текстур і фільтрації (для графіки — основне, іноді важливо і для операцій, схожих на семплінг);
ROPs займаються фінальним записом пікселів із блендингом та тестами глибини/стенсила.
Усі залежні від пропускної здатності пам’яті, поведінки кешів та драйвера/рантайму, який має тримати черги напханими.
В ML-інференсі ви зазвичай можете ігнорувати ROPs і TMUs — але «зазвичай» не означає «завжди».
Якщо ви рендерите, компонуєте, кодуєте/декодуєте відео або запускаєте змішані навантаження на одному GPU, ці блоки стають джерелом конкуренції.
У графіці баланс ROP/TMU постійно має значення.
В операційному сенсі: SMs/CUs — це ваші CPU‑ядерця, пропускна здатність пам’яті — ваш мережевий аплінк, кеші — ваш CDN, а ROPs/TMUs — спеціалізовані акселератори.
Якщо ви дивитесь лише на «GPU utilization», ви фактично оголошуєте сервіс здоровим, бо top показує 90% CPU — і потім дивуєтесь, чому p99 латентність горить.
Одна цитата, яка витримала десятиліття аварій: Надія — не стратегія.
— Джеймс Кемерон.
Якщо ви хочете надійності, ви вимірюєте систему, яку маєте, а не ту, яку бажали купити.
Анатомія GPU: ROPs, TMUs, SMs, CUs (та частини, про які забувають)
SMs (NVIDIA) та CUs (AMD): м’язи
NVIDIA називає їх Streaming Multiprocessors (SMs).
AMD називає їх Compute Units (CUs) (а в новіших архітектурах ви також почуєте про WGP — workgroup processors, які групують CUs).
Це блоки, що виконують більшість шейдерного коду та обчислювальних кернелів.
Кожен SM/CU містить кілька виконавчих ліній (думайте «SIMD/SIMT лінії»), регістри, планувальники та локальну пам’ять (shared memory / LDS).
Вони спроєктовані так, щоб тримати багато потоків «в польоті», щоб коли одна група зависає (часто на пам’яті), інша могла виконуватися.
Операційний переклад: SMs/CUs — це двигуни пропускної здатності. Їм подобається послідовна паралельна робота, і вони дратуються, коли їм дають дрібні серійні завдання,
сильну розгалуженість або шаблони доступу до пам’яті, які виглядають як розкидані по всьому полю дані.
Дві практичні наслідки:
- Occupancy (скільки варпів/wavefronts може бути резидентними) має значення, але не є самоціллю. Іноді нижча occupancy з кращою локальністю пам’яті перемагає.
- Тиск регістрів — тихий вбивця. Занадто багато регістрів на потік зменшує occupancy і збільшує спілови (spills) у локальну пам’ять, яка фактично є «глобальною пам’яттю у плащі».
TMUs: текстурні блоки (не тільки для ігор)
Texture Mapping Units (TMUs) традиційно виконують обчислення адрес текстур і фільтрацію.
У графіці вони вибирають дані текстур (часто з спеціалізованим кешем) і застосовують фільтри (білайнарний, трі- та анізотропний).
Це їхня основна робота.
У обчислювально інтенсивних ML‑завданнях ви, можливо, ніколи не досягнете ліміту TMU безпосередньо.
Але TMU може проявитися опосередковано, коли:
- ви робите перед/постобробку зображень на GPU;
- ви використовуєте апаратні шляхи семплінгу в графічних API;
- у вас змішані навантаження — рендеринг плюс обчислення — що ділять один чіп.
Якщо ваше навантаження важке на вибірці текстур, TMU може стати вузьким місцем навіть при достатній потужності шейдерів/обчислень.
У такому випадку «більше SMs» вас не врятує.
ROPs: відділ запису
ROPs (Raster Operations Pipelines) відповідають за перетворення піксельних даних, готових для запису у framebuffer, і виконують фінальні кроки:
блендинг, тести глибини/стенсила та запис у пам’ять.
Якщо запам’ятати одну річ: ROPs — це про запис пікселів назовні, а запис пікселів часто вимогливий до пропускної здатності пам’яті.
Ознаки вузького місця ROP з’являються у графічних навантаженнях при:
- високих роздільностях (4K і вище)
- великому overdraw
- активному блендингу (прозорість, пост‑процесинг)
- MSAA (більше семплів для запису)
У чистому compute ви можете зовсім не думати про ROPs — і це нормально — поки не виконаєте GPU‑композитинг, захоплення екрана, віддалений робочий стіл або відеооверлеї на тому самому GPU.
Тоді ви виявите, що «несуттєві» апаратні блоки фактично ділили пропускну здатність пам’яті та кеші з вашим «важливим» кернелем.
Підсистема пам’яті: частина, що псує вам день
Підсистема пам’яті GPU — це поєднання HBM/GDDR, контролерів пам’яті, кешу L2 і інтерконектів, що переміщують дані між SMs/CUs та VRAM.
Це часто справжнє вузьке місце, і їй байдуже на ваші теоретичні TFLOPS.
Якщо ваші кернелі обмежені пам’яттю, додаткова обчислювальна потужність не допоможе.
Якщо ви обмежені пропускною здатністю, виграшною стратегією зазвичай є:
краща локальність пам’яті, менше байтів у пересилці, ф’юзинг операцій, нижча точність (де безпечно),
або просто GPU з більшою пропускною здатністю.
Планувальники, черги та проблема «постачають vs голодніють»
GPU може бути технічно здоровим і водночас недозавантаженим, якщо хост не може його підживити:
конкуренція CPU‑потоків, Python GIL, синхронні копії, малі батчі, повільні даталоудери або драйвер, що застряг у серіалізації.
«GPU на 20%» — це не проблема GPU, поки ви не доведете протилежне.
Tensor‑ядра, RT‑ядра та інші: спеціалізовані блоки, що змінюють математику
Сучасні GPU мають спеціалізовані виконавчі блоки (Tensor Cores у NVIDIA, матричні блоки у AMD, RT‑ядра).
Вони не є SMs/CUs, але живуть поряд і можуть радикально змінити характеристики продуктивності.
Також вони часто вводять в оману: кернел може бути обчислювально важким, але не використовувати швидкі матричні блоки через типи даних, розкладку або вибір ядра.
Жарт №1: GPU — це як кухня ресторану — якщо мийник посуду (пропускна здатність пам’яті) повільний, найм більше кухарів (SMs) просто створює вищі стоси брудного посуду.
Цікаві факти та коротка історія (яка справді допомагає)
- ROPs передували «GPU compute», як ми його знаємо. Вони були центральними, коли графічні конвеєри були більш фіксованими, і ефективний запис пікселів був всім.
- Ранні епохи «shader model» зробили баланс SM/TMU продуктною стратегією. Вендори налаштовували чіпи під ігрові навантаження, де вибірки текстур + арифметика мали певні співвідношення.
- CUDA (епоха ~2007) допомогла ребрендингу SM як загального обчислювального двигуна. Раптом та сама кремнієва логіка, що малювала трикутники, почала робити лінійну алгебру та симуляції.
- Термінологія AMD «Compute Unit» виникла у подібному переході. «Compute Unit» звучить як одиниця, якою має керувати компілятор, а не тільки графічний драйвер.
- Текстурні кеші впливали на обчислювальні патерни. Деякі алгоритми спочатку використовували доступи, схожі на текстурні, бо той шлях мав кешування, якого звичайні завантаження тоді не мали.
- Fillrate колись був важливим рекламним показником. Піксельний fillrate (часто прив’язаний до кількості ROP і тактової частоти) був значним, коли шейдинг був простішим, а пропускна здатність виходу — жорсткою межею.
- Гонка за пропускною здатністю пам’яті триває довго. Покоління GDDR і HBM були не просто фешн‑оновленнями; вони вирішували вузьке місце, яке обчислювальні поліпшення постійно випереджували.
- Асинхронні обчислення та кращі планувальники змінили сенс «utilization». Високе значення utilization може ховати конкуренцію черг або неоптимальне перекриття копій/обчислень/графіки.
- Сучасні GPU з самого початку багатокористувацькі. Preemption, multi‑instance GPU (MIG) та віртуалізаційні можливості з’явилися тому, що продакшен вимагав ізоляції — не тому, що геймери ввічливо просили.
Що вимірювати і чому: метрики, які мають значення
Якщо ви відповідаєте за продуктивність і надійність, вам потрібно знати, який підсистему насичено:
обчислення, пропускна здатність пам’яті, кеші, PCIe/NVLink, графічний конвеєр або ланцюг підживлення з хосту.
Завдання не в тому, щоб «підняти GPU utilization». Завдання — «досягати SLO з передбачуваними витратами».
Обчислювально обмежене проти пам’яттю обмеженого: припиніть гадати
Обчислювально обмежене навантаження масштабується з:
більшою кількістю SMs/CUs, вищими тактовими частотами, кращим набором інструкцій, кращим використанням tensor/matrix ядер.
Пам’яттю обмежене навантаження масштабується з:
більшою пропускною здатністю, кращим хіт‑рейтом кешу, кращою коалесценцією, меншими читаннями/записами, ф’юзингом.
«Але мій utilization високий» сумісно з обома випадками.
Саме тому ви також дивитеся на пропускну здатність пам’яті та причини зупинок у профілювальниках.
ROPs і TMUs: коли вони важливі
Якщо ви оперуєте графічними навантаженнями (рендер‑фарми, VDI, стрімінг ігор, CAD), вам потрібна ясність по конвеєру на кадр:
обмежені ви шейдингом (SM/CU), вибіркою/фільтрацією текстур (TMU) чи записом/блендингом (ROP)?
Симптоми відрізняються:
- ROP‑обмеження: збільшення роздільності шкодить непропорційно; важкий блендинг вбиває; росте використання пропускної здатності.
- TMU‑обмеження: сцени з великою кількістю текстур падають у продуктивності, навіть якщо ALU‑util не максимальний.
- SM/CU‑обмеження: складні шейдери, інтенсивні обчислення на піксель, ray marching, важка математика.
Операційні «підводні камені» метрики
- Обмеження потужності / тротлінг: якщо GPU обмежено по енергії або термічно, ваші «очікувані» числа — вигадка.
- Помилки ECC / ремаппінг пам’яті: функції надійності можуть змінювати продуктивність; помилки можуть знижувати пропускну здатність або спричиняти відмови блоків.
- PCIe replay / пропускна здатність: передачі хост→пристрій можуть домінувати при малих батчах або надто частих копіях.
- Контекстні переключення / багатопроцесна конкуренція: кілька робочих місій можуть боротися за кеш, пропускну здатність пам’яті та час виконання.
- Домен тактових частот: такти пам’яті й SM можуть поводитися по-різному під обмеженнями.
Практичні завдання: команди, виводи та рішення (12+)
Це «я на виклику і мені потрібні відповіді» завдання. Кожне включає: команду, що означає вивід і рішення, яке треба прийняти.
Припускаємо Linux, NVIDIA‑інструменти де застосовно, і що ви маєте доступ до машини, за яку платите.
(AMD має подібні інструменти; логіка та сама, навіть якщо команда інша.)
Завдання 1: Підтвердити модель GPU, драйвер і базове здоров’я
cr0x@server:~$ nvidia-smi
Tue Jan 13 12:44:10 2026
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14 Driver Version: 550.54.14 CUDA Version: 12.4 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 NVIDIA A10 On | 00000000:17:00.0 Off | 0 |
| 30% 62C P0 138W / 150W | 19750MiB / 24576MiB | 92% Default |
+-------------------------------+----------------------+----------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
|=============================================================================|
| 0 N/A N/A 18342 C python 19600MiB|
+-----------------------------------------------------------------------------+
Що це означає: Підтверджує версію драйвера/CUDA, модель GPU, споживання потужності, температуру, використання пам’яті, завантаження і який процес володіє VRAM.
Рішення: Якщо пам’ять майже заповнена — підозрюйте фрагментацію/ризик OOM; якщо потужність на межі з високим Perf state — перевірте тротлінг; якщо GPU‑Util високий, але пропускна здатність низька — копайте глибше (пам’ять або причини зупинок).
Завдання 2: Перевірити причини тротлінгу (потужність/терміка/напрям)
cr0x@server:~$ nvidia-smi -q -d PERFORMANCE | sed -n '1,120p'
==============NVSMI LOG==============
Timestamp : Tue Jan 13 12:44:17 2026
Driver Version : 550.54.14
CUDA Version : 12.4
Performance State : P0
Clocks Throttle Reasons
Idle : Not Active
Applications Clocks Setting : Not Active
SW Power Cap : Active
HW Slowdown : Not Active
HW Thermal Slowdown : Not Active
Sync Boost : Not Active
SW Thermal Slowdown : Not Active
Що це означає: «SW Power Cap: Active» означає, що ви досягли налаштованого обмеження потужності; такти можуть знижуватися, щоб його дотримуватися.
Рішення: Якщо ви контролюєте термальні умови та енергетичний профіль, підвищте ліміт потужності (в межах специфікації) або покращіть охолодження. Якщо ні — скоригуйте очікування і планування потужності.
Завдання 3: Спостерігати utilization, такти, потужність і пам’ять у реальному часі
cr0x@server:~$ nvidia-smi dmon -s pucvmt -d 1
# gpu pwr gtemp mtemp sm mem enc dec mclk pclk
# Idx W C C % % % % MHz MHz
0 149 69 - 78 94 0 0 5001 1710
0 150 70 - 79 95 0 0 5001 1710
0 150 70 - 80 95 0 0 5001 1710
Що це означає: Отримуєте часовий ряд. Якщо SM% високий, але mem% теж високий — можливо ви обмежені пам’яттю або трешите кеші.
Рішення: Якщо mem% зафіксовано і продуктивність не росте — фокусуйтеся на байтах у пересилці (батчинг, ф’юзинг, точність). Якщо SM% низький — працюйте над підживленням (CPU, даталоадер, накладні витрати запуску).
Завдання 4: Перевірити ширину і швидкість PCIe (обмеження підживлення хостом)
cr0x@server:~$ nvidia-smi -q -d PCI | sed -n '1,120p'
PCI
Bus : 0x17
Device : 0x00
Domain : 0x0000
Bus Id : 00000000:17:00.0
PCIe Generation
Max : 4
Current : 3
Link Width
Max : 16x
Current : 8x
Що це означає: Кард підтримує Gen4 x16, але наразі працює на Gen3 x8. Це велике скорочення пропускної здатності між хостом і пристроєм.
Рішення: Пересадіть у слот, перемістіть слоти, перевірте налаштування BIOS, перевірте riser‑и і верифікуйте, як материнська плата ділить лінії. Якщо ваше навантаження інтенсивно передає дані, це може бути вся причина.
Завдання 5: Спостерігати використання GPU по процесах (багатокористувацька конкуренція)
cr0x@server:~$ nvidia-smi pmon -c 1
# gpu pid type sm mem enc dec command
# Idx # C/G % % % % name
0 18342 C 78 92 0 0 python
0 27711 C 12 7 0 0 python
Що це означає: Два процеси виконують обчислення на одному GPU. Маленький все одно коштує вам: контекстні переключення, тиск на кеш і конкуренція за пропускну здатність пам’яті.
Рішення: Якщо вам потрібні SLO за латентністю — ізолюйте навантаження (окремі GPU, MIG, політики планування). Якщо мета — пропускна здатність, співрозміщення може підходити, але вимірюйте взаємний вплив.
Завдання 6: Перевірити логи драйвера на ресети GPU або Xid‑помилки
cr0x@server:~$ sudo journalctl -k --since "2 hours ago" | egrep -i "NVRM|Xid|gpu|pcie" | tail -n 20
Jan 13 11:52:03 server kernel: NVRM: Xid (PCI:0000:17:00): 31, pid=18342, Ch 0000002b, MMU Fault: ENGINE GRAPHICS GPCCLIENT_T1_0 faulted @ 0x7f3a0000
Jan 13 11:52:03 server kernel: NVRM: Xid (PCI:0000:17:00): 31, pid=18342, Ch 0000002b, MMU Fault: Fault type: UNBOUND_INST
Що це означає: Xid‑помилки часто вказують на проблеми драйвера, апаратні або на рівні застосунку (неправильні звернення до пам’яті, поганий PCIe, нестабільні такти).
Рішення: Якщо Xid повторюються: ізолюйте хост/GPU, відтворіть під контрольованим навантаженням, оновіть драйвер/прошивку, запустіть стресс‑тести і розгляньте RMA, якщо підозри на апаратну несправність зростають.
Завдання 7: Підтвердити, що CPU не є справжнім вузьким місцем (підживлення GPU)
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0 (server) 01/13/26 _x86_64_ (64 CPU)
12:44:43 PM CPU %usr %nice %sys %iowait %irq %soft %steal %idle
12:44:44 PM all 92.1 0.0 7.1 0.0 0.0 0.3 0.0 0.5
12:44:44 PM 7 100.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
12:44:44 PM 8 100.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Що це означає: CPU‑ядерця перевантажені; кілька ядер залежать. Якщо ваш GPU‑робочий процес запускається з однопотокової петлі, ви можете голодувати пристрій.
Рішення: Профілюйте пайплайн хоста: потоки даталоудера, препроцесинг, серіалізація, накладні витрати Python. Збільшіть батчі, використовуйте асинхронні пайплайни або перенесіть препроцесинг на GPU.
Завдання 8: Перевірити локальність NUMA (PCIe‑пристрої не люблять трафік через інший сокет)
cr0x@server:~$ nvidia-smi topo -m
GPU0 CPU Affinity NUMA Affinity
GPU0 X 0-31 0
Що це означає: GPU0 прив’язаний до NUMA‑вузла 0; найкраща CPU‑афінність — 0‑31. Запуск потоку підживлення на іншому сокеті додає латентності і зменшує ефективну пропускну здатність PCIe.
Рішення: Прив’яжіть CPU‑потоки до правильного NUMA‑вузла і алокуйте хост‑пам’ять локально для копій.
Завдання 9: Підтвердити ефективну пропускну здатність PCIe під час передач
cr0x@server:~$ nvidia-smi dmon -s t -d 1
# gpu rxpci txpci
# Idx MB/s MB/s
0 5210 4980
0 5400 5102
0 5305 5055
Що це означає: RX/TX PCIe приблизно ~5 GB/s. Якщо ви очікували поведінки Gen4 x16 — ви недопідживлюєте пристрій.
Рішення: Зменшіть передачі (тримайте дані на GPU довше, ф’юзуйте операції), збільшіть розмір батчів, використовуйте pinned пам’ять і виправте проблеми з PCIe‑посиленням, якщо вони є.
Завдання 10: Перевірити інформацію про пам’ять GPU і ризик фрагментації
cr0x@server:~$ nvidia-smi --query-gpu=memory.total,memory.used,memory.free --format=csv
memory.total [MiB], memory.used [MiB], memory.free [MiB]
24576 MiB, 24010 MiB, 566 MiB
Що це означає: Ви фактично вичерпали VRAM. Навіть якщо «вміщається», фрагментація алокатора або раптовий сплеск може спричинити OOM.
Рішення: Зменшіть модель/батч, увімкніть оптимізації пам’яті (activation checkpointing де доречно), або ізолюйте це навантаження від усього іншого, що використовує VRAM.
Завдання 11: Визначити, чи GPU виконує графічну/дисплейну роботу (включає ROPs)
cr0x@server:~$ nvidia-smi --query-gpu=display_active,display_mode --format=csv
display_active, display_mode
Disabled, Disabled
Що це означає: Дисплей не підключено і режим дисплея вимкнено. Добре: менше несподіванок від композиції/ефектів робочого столу.
Рішення: Якщо дисплей активний на продакшн‑GPU для обчислень, подумайте про безголовий режим або окремий GPU для відображення/VDI. Змішане використання — джерело «загадкових ривків».
Завдання 12: Перевірити налаштування тактів GPU (хтось «оптимізував» вас у кут)
cr0x@server:~$ nvidia-smi -q -d CLOCK | sed -n '1,120p'
Clocks
Graphics : 1710 MHz
SM : 1710 MHz
Memory : 5001 MHz
Applications Clocks
Graphics : 1410 MHz
Memory : 5001 MHz
Що це означає: Application clocks встановлені нижче за пік графіки/SM. Це може обмежувати продуктивність, навіть якщо термали в нормі.
Рішення: Якщо це ненавмисно — скиньте application clocks або встановіть їх явно відповідно до вашої стратегії продуктивність/потужність.
Завдання 13: Підтвердити режим обчислень і режим persistence (поведінка для багатьох користувачів)
cr0x@server:~$ nvidia-smi --query-gpu=compute_mode,persistence_mode --format=csv
compute_mode, persistence_mode
Default, Enabled
Що це означає: Режим обчислень Default дозволяє кільком процесам; persistence увімкнено для уникнення повторної ініціалізації і зниження латентності першої задачі.
Рішення: Для суворої ізоляції розгляньте Exclusive Process режим (де застосовно). Тримайте persistence увімкненим для стабільної поведінки в продакшені.
Завдання 14: Підтвердити, що hugepages/IOMMU не саботують DMA (перевірки на рівні хоста)
cr0x@server:~$ dmesg | egrep -i "iommu|DMAR|vfio" | tail -n 10
[ 0.612345] DMAR: IOMMU enabled
[ 0.612900] DMAR: Intel(R) Virtualization Technology for Directed I/O
Що це означає: IOMMU увімкнено. Це може бути нормально, але неправильні налаштування можуть спричиняти накладні витрати або обмеження мапування в певних конфігураціях.
Рішення: Якщо ви бачите незвичну латентність передач або помилки мапування, перевірте налаштування IOMMU у вашому середовищі (особливо при passthrough/віртуалізації).
Завдання 15: Швидка «пам’ять‑це вузьке місце?» перевірка за спостережуваною пропускною здатністю
cr0x@server:~$ nvidia-smi --query-gpu=utilization.gpu,utilization.memory --format=csv -l 1
utilization.gpu [%], utilization.memory [%]
91 %, 96 %
92 %, 97 %
90 %, 96 %
Що це означає: Високе використання пам’яті поряд із високим використанням GPU часто вказує на пам’яттю обмежені кернелі або інтенсивний пам’яттєвий трафік (включно зі спіловами).
Рішення: Перейдіть до профілювання: перевірте пропускну здатність пам’яті, хіт‑рейти кешу та причин зупинок на рівні кернелів. Не витрачайте час на налаштування арифметики перш ніж це підтвердити.
Швидкий план діагностики: знайти вузьке місце за хвилини
Це шлях «не губитися у скріншотах профайлерів». Оптимізовано для триажу в продакшені.
Мета: визначити, чи обмежує вас підживлення, обчислення, пропускна здатність пам’яті, графічний конвеєр (TMU/ROP) або тротлінг/помилки.
Перше: санітарна перевірка і здоров’я (30–60 секунд)
- Запустіть
nvidia-smi. Перевірте: помилки, температури, потужність, використання пам’яті, активні процеси. - Перегляньте логи ядра на Xid/ресети (
journalctl -k). - Перевірте причини тротлінгу (
nvidia-smi -q -d PERFORMANCE).
Якщо ви знаходите ресети, сплески ECC або повторювані Xid — припиняйте полювання за продуктивністю. Займаєтесь надійністю.
Друге: GPU підживлюється? (2–3 хвилини)
- Подивіться на завантаженість CPU (
mpstat/top). - Перевірте стан лінка PCIe (Gen/width) і пропускну здатність PCIe (
nvidia-smi -q -d PCI,nvidia-smi dmon -s t). - Перевірте NUMA‑афінність (
nvidia-smi topo -m).
Якщо CPU забитий або PCIe знижено (неочікувано Gen3 x8), у вас проблема платформи, а не кернеля.
Третє: класифікуйте вузьке місце за поведінкою (5–10 хвилин)
- Обчислювально обмежене: SM зайнятість висока, memory util помірна; масштабується з тактами; краще з увімкненими tensor‑ядрами.
- Пам’яттю обмежене: memory util висока, продуктивність не росте з підвищенням SM тактів, чутливе до розміру батчів і ф’юзингу.
- TMU/текстурне обмеження (графіка): сцени, насичені текстурами, падають у продуктивності; зміни семплінгу/фільтрації впливають сильніше, ніж математика шейдера.
- ROP/вихідне обмеження (графіка): роздільність і блендинг сильно шкодять; записи виходу домінують; MSAA шкодить більше, ніж очікували.
Наступний інструмент залежить від класифікації. Якщо ви обчислювально обмежені — оптимізуйте кернелі і математику. Якщо пам’яттю обмежені — зменшуйте трафік і покращуйте локальність.
Якщо ROP/TMU‑обмеження — підправляйте налаштування рендерингу або обирайте апарат із іншим балансом.
Типові помилки: симптом → корінь проблеми → виправлення
1) «GPU utilization високий, але пропускна здатність низька»
Симптом: GPU‑Util 90%+, але кадрів/інференсів менше очікуваного.
Корінь проблеми: Кернелі, обмежені пам’яттю, треш кешу, спілови регістрів, або конкуренція від інших процесів.
Виправлення: Підтвердіть використання пам’яті і поведінку пропускної здатності; профілюйте на предмет зупинок/спілов; ф’юзуйте кернелі; зменшуйте точність, де безпечно; ізолюйте навантаження.
2) «GPU utilization низький, але латентність висока»
Симптом: GPU‑Util 10–30%, але p99 латентність погана.
Корінь проблеми: Підживлення хоста (CPU препроцесинг, малі батчі, синхронні копії) або накладні витрати на запуск кернелів.
Виправлення: Збільшіть батчі, організуйте пайплайн CPU/GPU, використовуйте асинхронні копії, прив’яжіть CPU‑потоки до локальних NUMA‑ядер, зменшіть кількість запусків на запит.
3) «Продуктивність суттєво різниться між ідентичними серверами»
Симптом: Та сама модель GPU, але один сервер повільніший на 20–40%.
Корінь проблеми: Тренування PCIe на знижений Gen/width, різні ліміти потужності, термальні умови або налаштування BIOS.
Виправлення: Порівняйте nvidia-smi -q -d PCI і причини тротлінгу; стандартизуйте прошивки/BIOS, перевірте охолодження, виправте розподіл ліній.
4) «Рендеринг падає при увімкненні прозорості або підвищенні роздільності»
Симптом: Сцена виглядає нормально, поки не додасте прозорість/пост‑процес; вища роздільність обвалює FPS.
Корінь проблеми: ROP/вихід і обмеження пропускної здатності; багато блендингу і overdraw збільшує трафік запису.
Виправлення: Зменшіть overdraw, оптимізуйте проходи блендингу, розгляньте буфери з нижчою точністю там, де це допустимо, і слідкуйте за пропускною здатністю пам’яті. Апарат з більшою кількістю ROP/пропускною здатністю допоможе.
5) «Сцени з великою кількістю текстур повільні, хоча шейдери прості»
Симптом: Проста математика, але продуктивність руйнується при високороздільних текстурах і фільтрації.
Корінь проблеми: TMU/вузьке місце вибірки текстур; промахи текстурного кешу; вартість анізотропної фільтрації.
Виправлення: Налаштуйте LOD текстур, зменшіть рівні фільтрації, стисніть текстури належним чином, зменшіть випадкове семплювання і розгляньте SKU GPU з кращою продуктивністю текстур, якщо потрібно.
6) «Після оновлення драйвера все стало повільніше»
Симптом: Той самий код, нижча пропускна здатність, можливо інша поведінка потужності.
Корінь проблеми: Інші налаштування за замовчуванням тактів/енергоменеджменту, змінений вибір кернелів або нові заходи безпеки.
Виправлення: Перевірте application clocks і power caps; валідируйте з контрольними бенчмарками; зафіксуйте відому робочу версію, якщо потрібна детермінована продуктивність.
7) «Ми купили більший GPU і отримали мало виграшу»
Симптом: Більше SMs/TFLOPS, але лише невелике прискорення.
Корінь проблеми: Ви були обмежені пам’яттю або PCIe; ви купили обчислення, але потрібна була пропускна здатність або кращий шлях даних.
Виправлення: Виміряйте передачі і пропускну здатність пам’яті; обирайте GPU з більшою пропускною здатністю (HBM), швидшими інтерконектами (NVLink) або переробіть канал даних.
Жарт №2: Найпростіший спосіб подвоїти продуктивність GPU — перестати надсилати йому той самий тензор тричі; на жаль, це трапляється частіше, ніж має бути.
Три корпоративні міні‑історії з бойових позицій
Міні‑історія 1: Інцидент через хибне припущення (ROPs не важливі… поки не стануть)
Компанія керувала флітом GPU для аналітики відео в реальному часі: декодування, інференс, накладання рамок та повторна кодування.
Вони вважали, що це «переважно обчислення», тому місткостну модель будували навколо завантаження SM та VRAM.
На вигляд усе було чисто. І це було помилкою.
Під час запуску продукту накладки ускладнилися: більше підписів, елементи інтерфейсу з alpha‑блендингом і додатковий пост‑процесинг.
Графи обчислень залишалися комфортними. Але потоки клієнтів почали втрачати кадри, і p95 латентність зросла.
Інженери ганялися за кернелями, змінювали розміри батчів, навіть відкатували модель. Нічого не допомагало.
Справжній винуватець — композиція виходу: блендинг і запис кадрів назад били по підсистемі пам’яті і фінальним стадiям пікселів.
Іншими словами, конвеєр став більш ROP‑орієнтованим і вимогливим до пропускної здатності.
GPU був «зайнятий», але не в тому сенсі, який очікувала модель.
Виправлення було нехитрим:
вони зменшили overdraw накладок, змінили стратегію композиції, щоб мінімізувати проходи блендингу, і рознесли обов’язки — обчислення на одному GPU, композитор/енкодер на іншому для найнавантаженіших вузлів.
Після цього система повернулась до передбачуваного масштабування. Урок не в тому, що «ROPs важливі». Урок у тому, що припущення дорогі.
Міні‑історія 2: Оптимізація, що вдарила у відкриту яму (гонитва за occupancy)
Інша команда мала CUDA‑кернел, який був повільніший, ніж очікувалося. Хтось знайшов блог з порадою «максимізуйте occupancy».
Вони переробили кернел, щоб використовувати менше регістрів і підвищили occupancy. Скриншот профілю виглядав краще.
Продуктивність у продакшені стала гіршою.
Зміна зменшила використання регістрів, але також збільшила глобальний трафік пам’яті через перерахунки значень і завантаження проміжних даних.
Кернел змістився з «помірно обчислювального» в «болісно обмежений пам’яттю».
Occupancy виросла. Продуктивність впала. Графіки обманювали, бо не вимірювали правильне обмеження.
Остаточне виправлення полягало в тому, щоб відмовитися від підходу «occupancy будь‑якою ціною»:
погодитися на нижчу occupancy, зберігати критичні значення в регістрах і перебудувати доступ до пам’яті для кращої коалесценції.
Також вони зф’юзили два сусідні кернелі, щоб уникнути запису проміжного тензора у VRAM.
Occupancy виглядала гірше; пропускна здатність покращилась суттєво.
Операційний висновок був ще ціннішим: вони додали перфоманс‑гейт до CI, який запускав репрезентативні кернелі і порівнював пропускну здатність пам’яті та розподіли часу виконання.
Наступна «хитра» зміна була зупинена до виходу в продакшен.
Міні‑історія 3: Нудна, але правильна практика, що врятувала день (стандартизація PCIe і потужності)
Платформна команда працювала з змішаними серверами GPU, придбаними в кілька хвиль.
На папері — та сама модель GPU, але різні материнські плати, версії BIOS і шасі з різною подачею повітря.
У них була непоказна вимога: кожен вузол повинен проходити «lane and clocks» acceptance тест перед входом у кластер.
Тест був нудним: перевірити PCIe Gen/width, виконати короткий трансферний бенчмарк, підтвердити ліміт потужності, підтвердити такти під тривалим навантаженням, переконатися в відсутності Xid‑помилок.
Це те, що люди називають бюрократією, поки не опиняться на виклику о 3 ранку.
Одного вікенду привезли партію вузлів із riser‑конфігурацією, що тихо тренувала GPU на знижену ширину ліній.
Без гейту ці вузли були б додані у пул і спричинили б випадкові повільні задачі, періодичні таймаути і нескінченні запити щодо продуктивності.
Натомість гейт відфейлив їх одразу. Виправили до того, як клієнти щось помітили.
Перемога полягала не в «зловили помилку». Перемога — в запобіганні класу нестабільної поведінки від потрапляння в систему.
Продакшен любить нудні, повторювані перевірки.
Чеклісти / покроковий план
Чекліст A: Коли хтось каже «GPU повільний»
- Визначте тип навантаження: тільки обчислення, тільки графіка чи змішане (включно з декодом/енкодом/дисплеєм/композитором).
- Перевірте здоров’я GPU:
nvidia-smi, версії драйвера, температури, потужність, помилки. - Перевірте причини тротлінгу: power cap, thermal slowdown, application clocks.
- Підтвердіть лінк платформи: PCIe Gen/width, NUMA‑локальність, пропускну здатність PCIe під навантаженням.
- Перевірте багатокористувацьку конкуренцію: використання по процесах; підтвердіть припущення про планування/ізоляцію.
- Класифікуйте вузьке місце: compute‑bound vs memory‑bound vs feed‑bound; для графіки врахуйте поведінку TMU/ROP.
- Тільки після цього відкривайте профайлер — і йдіть туди з гіпотезою.
Чекліст B: Перед купівлею обладнання або масштабуванням кластера
- Виміряйте поточне вузьке місце (не лише utilization).
- Якщо пам’ять обмежує, пріоритет наразі — покращення пропускної здатності/кешу та зміни в ПЗ, а не більше обчислення.
- Якщо обмежені передачі, пріоритет — інтерконект і локальність даних (PCIe Gen, NVLink, NUMA pinning).
- Якщо ROP/TMU‑обмеження (графіка), обирайте SKU з відповідним балансом; не купуйте обчислення, яке не зможете підживити або записати.
- Плануйте ізоляцію: MIG, виділені GPU для latency‑чутливих сервісів, або принаймні cgroup‑рівень та політики планування.
- Стандартизовуйте acceptance тест: ширина ліній, такти під навантаженням, налаштування power cap, чисті логи помилок.
Чекліст C: Безпечний цикл налаштування продуктивності (який не створює інцидентів)
- Оберіть одне репрезентативне навантаження. Не мікробенчмарк, якщо тільки він не відображає реальний продакшен.
- Зафіксуйте базові показники: пропускну здатність, розподіл латентності, потужність, температури, використання пам’яті, пропускну здатність PCIe.
- Змініть одну річ. Одна.
- Повторно виміряйте і порівняйте розподіли, а не лише середні значення.
- Впроваджуйте, тільки якщо розумієте, чому стало краще, і можете пояснити нові режими відмов.
- Додайте регресійний гейт, якщо зміна важлива (CI‑завдання, канарка або нічний перформанс‑прогін).
Питання та відповіді
1) Яке просте визначення SMs і CUs?
Це основні блоки виконання, які виконують паралельні потоки для шейдерів і обчислювальних кернелів.
NVIDIA називає їх SMs; AMD — CUs. Різні внутрішні рішення, але схожа роль: робити математику і ховати латентність великою кількістю паралельної роботи.
2) Чи «CUDA cores» — те саме, що SMs?
Ні. «CUDA cores» — маркетингове підрахування скалярних ALU‑ліній по всім SMs.
SM — це одиниця, що планує і керує роботою; вона містить кілька виконавчих блоків, регістрів і спільну пам’ять.
3) Що насправді роблять TMUs і чому мені про це хвилюватися?
TMUs вибирають дані текстур і ефективно застосовують фільтрацію. У графіці ліміти TMU реальні і помітні.
У compute вони важливі, коли навантаження використовує шлях семплінгу текстур або коли змішані навантаження створюють конкуренцію за пам’ять/кеші.
4) Що роблять ROPs і коли вони стають вузьким місцем?
ROPs обробляють фінальні операції над пікселями: блендинг, depth/stencil і запис пікселів у framebuffer.
Вони стають вузьким місцем, коли домінують записи виходу: висока роздільність, важкий блендинг, багато overdraw, MSAA або сценарії з обмеженою пропускною здатністю.
5) Чому інколи підвищення роздільності так сильно шкодить продуктивності?
Більше пікселів означає більше роботи на пізніших етапах конвеєру і більше трафіку пам’яті.
Якщо ви обмежені ROP/пропускною здатністю, подвоєння кількості пікселів може обрушити FPS, навіть якщо обчислення не максимально завантажені.
6) Чому GPU utilization низький, хоча моя програма «користується GPU»?
Поширені причини: вузьке місце в CPU‑підготовці, малі батчі, синхронні копії хост→пристрій, накладні витрати на запуск кернелів або очікування I/O.
Низьке utilization часто означає, що GPU просто чекає на роботу.
7) Чи завжди висока occupancy — добре?
Ні. Occupancy — це інструмент для приховування латентності, а не трофей.
Для деяких кернелів більша occupancy підвищує трафік пам’яті або змушує спілити регістри. Критерій успіху — пропускна здатність і латентність під реальним навантаженням, а не одне число.
8) Як ROPs/TMUs пов’язані з ML‑інференсом?
Зазвичай — не пов’язані, поки ви не виконуєте перед/постобробку, композинг або відео на тому самому GPU.
Також усе, що підвищує тиск на пропускну здатність пам’яті, опосередковано може погіршити ML‑пропускну здатність, навіть якщо ROPs/TMUs безпосередньо не використовуються.
9) Який найшвидший спосіб визначити, чи я обмежений пам’яттю?
Спостерігайте за використанням пам’яті і пропускною здатністю під навантаженням, потім змініть щось, що повинно підвищити обчислення (наприклад, такти SM або швидший обчислювальний SKU).
Якщо продуктивність майже не змінюється — ймовірно ви обмежені пам’яттю. Підтвердіть профілюванням зупинок/пропускної здатності.
10) Чи варто ділити GPU між сервісами в продакшені?
Тільки якщо ви можете терпіти взаємний вплив і вимірюєте його.
Для латентно‑чутливих навантажень ізолюйте через виділені GPU або MIG/партиціювання. «Працювало в стейджингу» — це не політика планування.
Висновок: практичні наступні кроки
ROPs, TMUs, SMs і CUs — це не дрібниці. Це карта того, де ваша робота може застрягти.
Коли ви діагностуєте за етапом конвеєру — підживлення, обчислення, пам’ять, запис — ви припиняєте гадати і починаєте виправляти.
Наступні кроки, які швидко окупаються:
- Додайте легкий acceptance тест вузла GPU: PCIe Gen/width, тривалі такти під навантаженням, відсутність Xid‑помилок, стабільна потужність/температури.
- Інструментуйте сервіси метриками пропускної здатності і розподілами латентності разом із метриками GPU/CPU/PCIe. Середні — милі. p99 платить вашу зарплатню.
- Коли продуктивність регресує — пройдіть швидкий план діагностики перед тим, як чіпати код. Половина «GPU‑проблем» — це платформа і пайплайн.
- Для графіки/змішаних навантажень явно враховуйте TMU/ROP і обмеження пропускної здатності. Якщо ви не моделюєте вартість запису, вона змоделює вас.