Якщо вам колись доводилося шукати причину в тікеті «GPU повільний» три години, щоб виявити, що вузьке місце — однопотоковий цикл підтвердження команд на CPU, ви вже розумієте головну ідею:
графічне обладнання не просто стало швидшим. Воно стало окремим. Інша пам’ять. Інше планування. Інші режими відмов. Інша правда.
Сучасний GPU — це не «акселератор», прикручений до ПК. Це повноцінна система зі своїми обмеженнями та власною операційною гравітацією. Цей розкол почався в 1990-х,
коли 3D-карти перестали бути милими доповненнями й почали перетворюватись на незалежні світи, які професійно малюють трикутники.
Від blitter до світу: момент, коли графіка перестала бути «просто картою»
Ранні ПК-відеоісторії були фундаментально про CPU. «Графічна карта» виконувала вивід на дисплей і трохи 2D-ускорення — bit blit-и, малювання ліній, можливо апаратний курсор.
Але пайплайном володів CPU. Якщо ви хотіли 3D, ви робили математику на CPU і штовхали пікселі в буфер кадру, ніби друкуєте сторінку.
Потім ігри стали амбіційнішими і CPU перетворився на вузьке місце планування. Не тому, що CPU «повільні» як такі, а тому, що 3D-рендеринг — це конвеєр:
трансформації, освітлення, відсікання, растеризація, текстурування, блендінг, тести z-буфера. Робіть це на 30–60 кадрів на секунду для тисяч трикутників з кількома текстурами —
і ваш CPU стає недоплачуваним стажером із купою форм.
Прорив полягав не лише в швидкості. Він полягав у спеціалізації. 3D-акселератори взяли конкретні частини того пайплайну й реалізували їх у залізі — спочатку як блоки з фіксованим функціоналом.
Ці блоки були детерміністичними, масово паралельними (на той час) і оптимізованими під пропускну здатність та локальність. Вони не були універсальними, але й не мали бути. У них була одна робота.
Коли такі блоки з’явилися, вони відтягнули центр тяжіння від CPU. Потреби GPU — пропускна здатність VRAM, складність драйверів, DMA-подача команд, перемикання контекстів — стали
першорядними інженерними обмеженнями. Тут «GPU став окремим світом» перестає бути метафорою і стає вашим досвідом при реагуванні на інциденти.
Жарт №1: GPU — це колега, який неймовірно швидкий, але говорить тільки пакетами; якщо ви ставите одне питання за раз, обом буде сумно.
Історичні факти, що мають значення в операціях
Ось конкретні історичні точки, які не є дрібницями — вони пояснюють, чому сучасні GPU поводяться так, як поводяться, особливо під навантаженням і в продакшені.
- 3D-карти середини 1990-х відвантажували растеризацію і мапінг текстур, тоді як CPU часто все ще обробляв геометричні трансформації. Цей розподіл створив патерн «вузьке місце при подачі команд», який досі існує.
- 3dfx Voodoo (1996) популяризував спеціалізоване 3D-залізо і ввів багатьох у концепт окремого 3D-пайплайну — часто як другої карти, а не основного дисплея.
- Direct3D vs OpenGL — це було не лише про API-релігію. Це вплинуло на моделі драйверів, припущення рушіїв і те, як швидко фічі ставали загальними — тобто, на те, що вендори оптимізували.
- AGP (кінець 1990-х) намагався надати графіці дружній шлях до головної пам’яті через GART (Graphics Address Remapping Table). Це був ранній урок «спільна пам’ять — не безкоштовна».
- Програмовані шейдери (початок 2000-х) перемістили GPU від фіксованого функціоналу до програмованого пайплайну. Це початок GPU як загального масово-паралельного обчислювального двигуна.
- Hardware T&L (transform and lighting) перемістив основну геометрію на GPU, зменшивши навантаження CPU, але збільшивши складність драйверів і команд.
- Уніфіковані шейдерні архітектури пізніше замінили окремі вершинові/піксельні конвеєри, покращивши утилізацію — але зробивши продуктивність менш передбачуваною без профілювання.
- Мульті-GPU (ерa SLI/CrossFire) дала неприємний операційний урок: «більше карт» може означати «більше синхронізації», плюс більше дивностей драйвуера, а не лінійне прискорення.
Старий 3D-пайплайн: чому фіксований функціонал змінив усе
Щоб зрозуміти народження 3D-акселераторів, потрібно розуміти, що саме вони пришвидшували: пайплайн, що природно розбивається на повторювані математичні кроки.
Ранній архітектурний бet полягав у тому, що ці кроки були достатньо стабільними, щоб їх зафіксувати в апаратурі.
Блоки з фіксованим функціоналом: передбачувані, швидкі й дивно крихкі
Фіксований функціонал означає, що в силіконі є виділені блоки: налаштування трикутника, растеризація, семплювання текстур, блендінг, тестування глибини.
Ви даєте параметри — він виконує задачу. Це швидко, бо немає накладних расходов на декодування інструкцій, а шляхи даних налаштовані під конкретну операцію.
Це також крихко: коли індустрія хоче нову модель освітлення чи інший комбайнер текстур, ви не можете «залатати» апаратне забезпечення.
Операційно епоха фіксованого функціоналу породила специфічний набір проблем: одна обхідна логіка драйвера могла вирішити, чи працюватиме ваш рушій на 60 FPS або впаде при запуску.
З фіксованим залізом вендори наштовхували сумісні шари в драйвери, і драйвер став м’яким емулятором відсутніх можливостей.
Така спадщина ніколи повністю не зникла; вона просто перемістилась шарами.
Подача команд: початок асинхронності GPU
CPU не «викликає GPU» як функцію. Він будує буфери команд і подає їх. GPU споживає їх, коли може.
Ця асинхронна модель зародилася рано, бо це був єдиний спосіб тримати й CPU, й GPU зайнятими.
Саме тому налагодження продуктивності складне. Ваш CPU може чекати на fence; GPU може чекати на дані; час кадру може домінуватися завантаженням текстур, про яке ви забули.
Якщо ви ставитесь до GPU як до синхронного копроцесора, ви неправильно діагностуєте вузьке місце і «полагодите» не ту компоненту.
Ключова концепція: тримати «гарні» дані поруч із місцем їхнього використання
Текстури та буфери кадру поглинають багато пропускної здатності. Ранні акселератори зробили різку, але правильну ставку: тримати їх у локальній VRAM на карті.
Це зменшує затримки і уникати насичення системної шини. Це також створює новий ресурс для управління: тиск VRAM, резидентність, пейджинг, фрагментація.
VRAM, пропускна здатність і чому GPU потребував власного королівства пам’яті
GPU став окремим світом, бо він потребував власної економіки. Ця економіка вимірюється в байтах за секунду, а не в GHz.
CPU-інженери люблять частоти; GPU-інженери рахують байти в секунду, а потім все одно скаржаться.
Чому існує VRAM: передбачувана пропускна здатність краща за хитромудрість
GPU потрібно читати текстури, записувати колорові буфери, читати буфери глибини і робити це паралельно. Цей шаблон доступу не схожий на CPU.
CPU процвітають на кешах і предиктах переходів; GPU процвітають на стрімах і приховуванні затримок через паралелізм. VRAM проєктований для широких шин і високої пропускної здатності.
Ранні підходи «використовувати системну RAM для текстур» (включно з AGP-текстуруванням) виглядали привабливо на папері. На практиці шина ставала горлом,
а варіація затримок викликала підвисання. Це повторюваний урок: спільні ресурси — це місце, куди йде продуктивність під конкурентним навантаженням.
Резидентність і пейджинг: мовчазний рушій підвисань
Коли у вас є окрема VRAM, потрібно мати політику щодо того, що там зберігається. Коли VRAM заповнена, щось мусить бути вигнано.
Якщо звільнення відбувається під час кадру — отримуєте піки. Якщо під час малювання — отримуєте стаги.
Сучасні API дають більш явний контроль (і більше відповідальності), але режим відмови старий: забагато текстур, забагато render target-ів, замало пам’яті.
Математика пропускної здатності, яка змінює рішення
Інженери люблять сперечатися про «compute vs memory bound». У графіці часто перемагає пропускна здатність. Якщо ваш шейдер простий, але текстури великі і render target високої роздільності,
ваш GPU може нудьгувати в очікуванні даних.
В операційних термінах: якщо ви бачите низьку утилізацію GPU при високому часі кадру, можливо, ви обмежені пам’яттю, PCIe або подачею команд. Правильний інструмент — вимір, а не інтуїція.
AGP до PCIe: війни шин і уроки
Системний інтерконект визначає, наскільки можлива «світова відокремленість». Коли GPU був на PCI, він конкурував з усім іншим. AGP дав йому швидший, більш прямий шлях,
плюс механізми на кшталт GART для мапування системної пам’яті. Потім з’явився PCIe і перетворив GPU на периферію з високою пропускною здатністю та масштабованими лініями.
AGP: спеціальне ставлення, спеціальні режими відмов
AGP був «специфічним для графіки», а отже мав «специфічні графічні баги». На практиці ви могли отримати нестабільність, яка проявлялась тільки коли гра агресивно стріміла текстури.
Такий тип відмови — улюблене місце менеджерів інцидентів, бо виглядає як випадкова корупція, поки не помітиш кореляцію зі спайками пропускної здатності.
PCIe: масштабовано, але не чарівно
PCIe дає лінії, швидкості лінку і звітність помилок. Він також дає нові способи помилитися: переговори на нижчій ширині лінку, події перетренування, скориговані помилки, що тихо погіршують продуктивність,
і скидання пристрою під навантаженням.
Якщо ви не моніторите стан PCIe, ви поводитесь з GPU як з чорним ящиком. Саме так ви починаєте «оптимізувати шейдери», щоб виправити глючний райзер.
Драйвери: де хороші ідеї зустрічаються з фізикою і дедлайнами
Драйвер — це договір між двома світами. Він перекладає виклики API у буфери команд, керує пам’яттю, планує роботу, обробляє стани енергозбереження
і намагається залишатися стабільним, поки додатки роблять креативні речі з невизначеною поведінкою.
Саме тому «в мене працює на моєму машині» особливо марно в світі GPU. Версія драйвера, версія ядра, прошивка, мікрокод і навіть BIOS материнської плати можуть змінити поведінку.
Ви можете бути технічно праві і все одно впасти.
Цитата, яку варто тримати на стикері
«Сподівання — не стратегія.» — Генерал Гордон Р. Салліван
Ставтесь до надійності GPU так само, як до надійності сховища: вважайте шлях щасливого сценарію демонстрацією, а не контрактом. Інструментуйте, перевіряйте і явно фіксуйте версії.
API формували апаратне забезпечення
Direct3D і OpenGL не лише відкривали можливості; вони формували пріоритети команд по виготовленню силікону. Фіксовані пайплайни добре вкладались у ранні API.
Пізніше моделі шейдерів змусили до програмованості, і апаратне забезпечення еволюціонувало, щоб запускати малі програми в масштабі.
Операційна порада: якщо ваш стек використовує високорівневу абстракцію (рушій, рантайм, фреймворк), абстракція може протікати старими припущеннями про те, як працюють GPU.
Коли щось ламається, спочатку читайте логи драйвера та повідомлення ядра, а не маркетингову презентацію.
Три корпоративні міні-історії з реального світу
Міні-історія №1: інцидент через неправильне припущення
Медіакомпанія експлуатувала флот серверів для транскодування з підтримкою GPU. Пайплайн був переважно стабільний: ingest, decode, фільтри, encode, публікація.
Одного ранку латентність завдань подвоїлась, черга почала зростати. Дашборди CPU і GPU здавалися «в порядку», що зазвичай означає — ви витратите час даремно.
Позиція on-call була такою: «Якщо утилізація GPU низька, GPU не є вузьким місцем». Тож вони масштабували CPU-ноди, підвищували кількість воркерів і налаштовували пул потоків.
Черга продовжувала зростати. Ноди з GPU не показували очевидних червоних прапорців, крім випадкових падінь пропускної здатності PCIe — ігнорували це, бо не мали базової лінії.
Насправді причиною було оновлення прошивки на підмножині серверів, яке після гарячих перезавантажень виразно зменшувало ширину PCIe-лінку.
GPU «не були зайняті», бо їх морили голодом: DMA-перекази та завантаження фреймів відео були повільнішими, тож пайплайн проводив більше часу в очікуванні копій.
Виглядало, ніби GPU просто холостує, але система була обмежена через I/O.
Виправлення було нудним: перерахунок інвентарю та забезпечення параметрів PCIe, додати алерти на зміну ширини/швидкості лінку і фіксувати оновлення прошивки в вікнах техобслуговування з валідацією.
Урок був гострим: низька утилізація може означати голод, а не запас. Розглядайте «простій» як симптом, а не остаточний висновок.
Міні-історія №2: оптимізація, яка призвела до відкату
Команда фінтеху мала дашборд реального часу з візуалізацією складних 3D-сцен — бо хтось вирішив, що 2D-графіки не «іммерсивні».
Вони оптимізували шляхом агресивного батчінгу викликів малювання й рідкісної загрузки більших текстурних атласів. FPS у лабораторії покращився.
У продакшені користувачі почали скаржитися на періодичні підвисання: додаток йшов плавно, потім «завмирав» на півсекунди. Графіки CPU показували спайки.
Профілювання GPU показало довгі стаги у непередбачувані моменти. Команда звинувачувала збирач сміття, потім мережу, потім «Windows» — що не було кореневою причиною.
Реальна проблема була в тиску VRAM і зміні резидентності. Більші атласи зменшили частоту завантажень, але коли завантаження відбувалося, воно було масивним,
і система іноді мусила вигнати render target-и, щоб упхнути нові дані. Драйвер робив неявний пейджинг і синхронізацію у найгірший можливий момент.
Оптимізація зросила пікове споживання пам’яті і зробила події стагів рідшими, але катастрофічно більшими.
Вони виправили це, тримаючи атласи нижче порогу резидентності, розбиваючи завантаження на менші шматки і явно бюджетуючи VRAM.
Середній FPS трохи впав; хвостова латентність покращилась драматично. Користувачі надають перевагу стабільним 45 FPS над «іноді 90, іноді заморожено».
Міні-історія №3: нудна, але правильна практика, яка врятувала день
SaaS-компанія пропонувала віртуальні робочі станції з підтримкою GPU. Нічого гламурного: CAD, відеомонтаж, кілька ноутбуків для ML.
Вони мали суворий процес змін для драйверів і прошивок GPU: поступове розгортання, канарки та автоматичний відкат при підвищенні рівня помилок.
Це не подобалося розробникам, бо уповільнювало «отримання останніх приростів продуктивності».
Якось кварталі нова версія драйвера покращила пропускну здатність у кількох бенчмарках і виправила відому графічну артефактність.
Вона також внесла рідкісне скидання GPU під певною комбінацією мультимоніторних розкладок і високих частот оновлення.
Баг не проявлявся в синтетичних тестах. Він проявився в реальних робочих потоках клієнтів — бо реальність завжди проявляє.
Канаркова група його зловила. Логи ядра показали помилки типу Xid і скидання, корельовані зі змінами конфігурації дисплея.
Розгортання зупинили на невеликому відсотку нод, клієнтів автоматично перемістили, і інцидент обмежився кількома сесіями.
Практика, що їх врятувала, не була хитрою. Це було контрольоване розгортання плюс спостережуваність.
Нудна правильність — ось як не дати GPU перетворити чергу підтримки на перформанс-арт.
Практичні завдання: команди, виводи, значення та рішення
Ви не зможете налагодити GPU, дивлячись лише на одне число утилізації. Потрібні докази: швидкість лінку, тиск пам’яті, помилки драйвера, подача команд CPU і поведінка по теплу/енергії.
Нижче — практичні, виконувані завдання на поширених системах Linux. Кожне включає: команду, приклад виводу, що це означає і яке рішення приймати.
1) Визначити GPU і драйвер, що використовується
cr0x@server:~$ lspci -nnk | grep -A3 -E "VGA|3D controller"
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA102 [GeForce RTX 3090] [10de:2204] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:3897]
Kernel driver in use: nvidia
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
Значення: Підтверджує, який пристрій і який драйвер ядра активні. Якщо ви очікували датацентричний GPU, а бачите споживчу модель — ви вже дебажите закупівлю, а не продуктивність.
Рішення: Якщо використовується неправильний драйвер (наприклад, nouveau), виправте вибір драйвера перед тим, як чіпати код додатку.
2) Перевірити швидкість і ширину PCIe-лінку (критично для «GPU простий, але повільно»)
cr0x@server:~$ sudo lspci -s 01:00.0 -vv | grep -E "LnkCap:|LnkSta:"
LnkCap: Port #0, Speed 16GT/s, Width x16, ASPM L1, Exit Latency L1 <64us
LnkSta: Speed 8GT/s (downgraded), Width x8 (downgraded)
Значення: Карта підтримує PCIe Gen4 x16, але працює на Gen3 x8. Це може суттєво урізати пропускну здатність для передач.
Рішення: Розбирайтеся з налаштуваннями BIOS, райзерами, розташуванням слота або цілісністю сигналу. Не «оптимізуйте ядра», щоб компенсувати зниження лінку.
3) Шукати скориговані помилки PCIe і перетренування лінку
cr0x@server:~$ sudo dmesg -T | grep -iE "pcie|aer|corrected|link"
[Mon Jan 13 09:22:10 2026] pcieport 0000:00:01.0: AER: Corrected error received: 0000:01:00.0
[Mon Jan 13 09:22:10 2026] nvidia 0000:01:00.0: PCIe Bus Error: severity=Corrected, type=Physical Layer
Значення: Скориговані помилки можуть бути запахом проблем з продуктивністю і стабільністю. Проблеми фізичного рівня часто вказують на проблеми з кабелями/райзером/слотом.
Рішення: Якщо помилки корелюють з навантаженням, заплануйте апаратний огляд і розгляньте переміщення GPU в інший слот/нод.
4) Спостерігати утилізацію GPU, пам’ять, енергоспоживання й частоти (NVIDIA)
cr0x@server:~$ nvidia-smi
Tue Jan 13 09:25:01 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. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA RTX 3090 Off | 00000000:01:00.0 Off | N/A |
| 30% 72C P2 310W / 350W| 22500MiB / 24576MiB | 18% Default |
+-----------------------------------------+----------------------+----------------------+
Значення: Низький GPU-Util при дуже високому використанні VRAM натякає на тиск пам’яті, синхронізацію або I/O-голодування — не обов’язково запас потужності.
Рішення: Якщо VRAM майже заповнений, профілюйте алокації і зменшуйте пікову резидентність (менші батчі, стрімінг, зниження роздільності render target-ів).
5) Дивитись статистику GPU в реальному часі, щоб ловити спайки й тротлінг
cr0x@server:~$ nvidia-smi dmon -s pucvmt
# gpu pwr gtemp mtemp sm mem enc dec mclk pclk fb bar1
# Idx W C C % % % % MHz MHz MB MB
0 315 74 - 22 55 0 0 9751 1695 22510 256
Значення: Потужність і частоти показують, чи ви тротлите. Якщо pclk падає, а температура зростає — ви термічно або енергетично обмежені.
Рішення: Покращіть охолодження, відрегулюйте енергокапи або зменшіть тривале навантаження. Не гоньтесь за «мікрооптимізаціями», поки працюєте на знижених частотах.
6) Шукати скидання GPU або збої драйвера в логах
cr0x@server:~$ sudo journalctl -k -b | grep -iE "nvrm|xid|amdgpu|gpu fault|reset"
Jan 13 09:18:44 server kernel: NVRM: Xid (PCI:0000:01:00): 79, GPU has fallen off the bus.
Jan 13 09:18:44 server kernel: nvidia: probe of 0000:01:00.0 failed with error -1
Значення: «Fallen off the bus» свідчить про серйозну проблему PCIe/апаратури/прошивки, а не про баг додатку.
Рішення: Ставте це як апаратну нестабільність: пересіть, перемістіть у інший слот, перевірте живлення, оновіть прошивку обережно і карантинуйте нод.
7) Перевірити IOMMU-групи і відображення віртуалізації (поширено на GPU-серверах)
cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do echo "$d"; done | grep -E "01:00.0|01:00.1"
/sys/kernel/iommu_groups/18/devices/0000:01:00.0
/sys/kernel/iommu_groups/18/devices/0000:01:00.1
Значення: GPU і його аудіофункція в одній IOMMU-групі. Це типовo; passthrough вимагає ізоляції груп для безпеки і стабільності.
Рішення: Якщо несподівані пристрої ділять групу, налаштуйте BIOS ACS або розташування плат до спроби чистого passthrough.
8) Виміряти вузькі місця на боці CPU при подачі команд
cr0x@server:~$ pidof my-renderer
24817
cr0x@server:~$ sudo perf top -p 24817
Samples: 61K of event 'cpu-clock', 4000 Hz, Event count (approx.): 15250000000
Overhead Shared Object Symbol
18.22% libc.so.6 pthread_mutex_lock
12.91% my-renderer SubmitCommandBuffer
9.77% libvulkan.so.1 vkQueueSubmit
Значення: Велика частка часу у локах і функціях подачі команд вказує, що обмежує CPU, а не продуктивність шейдерів.
Рішення: Зменшіть накладні витрати на подачу: батчінг станів, багатопотокова підготовка команд, уникайте блокувань per-draw.
9) Підтвердити впливи huge page / тиску пам’яті на GPU-ворклоади
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
6 0 0 81264 10240 512000 0 0 0 12 2310 5400 72 18 8 2 0
8 0 0 62400 9984 498112 0 0 0 40 2600 6800 78 19 2 1 0
Значення: Велика кількість runnable-потоків (r) і низький idle (id) вказують на конкуренцію CPU. Це не обов’язково погано, але означає, що «GPU повільний» може бути через голод CPU.
Рішення: Прив’язуйте потоки, зменшуйте пересичення CPU або переносіть GPU-завдання на ноди з запасом CPU.
10) Перевірити обмеження cgroup CPU (контейнеризовані GPU-додатки)
cr0x@server:~$ cat /sys/fs/cgroup/cpu.max
200000 100000
Значення: Цей контейнер обмежений еквівалентом 2 CPU (200ms на 100ms період). Це може обмежувати подачу команд і підготовку даних.
Рішення: Підвищте CPU-ліміти для GPU-ворклоадів; голодний CPU робить GPU «недоутилізованим» і вводить у замішання всіх.
11) Перевірити файлову систему і I/O wait при стрімінгу ресурсів
cr0x@server:~$ iostat -xz 1 3
avg-cpu: %user %nice %system %iowait %steal %idle
55.12 0.00 8.22 20.45 0.00 16.21
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
nvme0n1 950.0 120000.0 0.0 0.00 7.20 126.32 110.0 24000.0 3.10 7.20 92.0
Значення: Високий iowait і висока зайнятість NVMe означають, що стрімінг активів може блокувати рендеринг/обчислювальні пайплайни в очікуванні даних.
Рішення: Попередньо завантажуйте гарячі активи, збільшуйте кеш, переходьте на швидше сховище або реструктуруйте стрімінг, щоб не блокувати рендер-потік.
12) Відслідковувати процеси, що споживають пам’ять на GPU (NVIDIA)
cr0x@server:~$ nvidia-smi pmon -c 1
# gpu pid type sm mem enc dec command
# Idx # C/G % % % % name
0 24817 C 20 88 0 0 my-renderer
0 25102 C 2 6 0 0 python
Значення: Другий процес використовує VRAM. Це може викликати пейджинг і створювати латентні спайки для основного ворклоаду.
Рішення: Забезпечте ізоляцію (виділені GPU на ворклоад, політики планування або MIG, де доступно) і перестаньте вважати VRAM «спільною за замовчуванням».
13) Підтвердити наявність вузлів пристроїв і права доступу (класична контейнерна помилка)
cr0x@server:~$ ls -l /dev/nvidia*
crw-rw-rw- 1 root root 195, 0 Jan 13 09:10 /dev/nvidia0
crw-rw-rw- 1 root root 195, 255 Jan 13 09:10 /dev/nvidiactl
crw-rw-rw- 1 root root 195, 254 Jan 13 09:10 /dev/nvidia-modeset
Значення: Вузли пристроїв існують. Якщо контейнер їх не бачить — це проблема конфігурації runtime, а не «CUDA зламалась».
Рішення: Виправте passthrough GPU для контейнера, правила cgroup для пристроїв або права udev.
14) Підтвердити, що версії модулів ядра збігаються з інстальованим стеком
cr0x@server:~$ modinfo nvidia | head
filename: /lib/modules/6.5.0-18-generic/updates/dkms/nvidia.ko
version: 550.54.14
license: NVIDIA
description: NVIDIA kernel module
Значення: Версія модуля ядра має збігатися з userspace-інструментами. Невідповідності можуть викликати тонкі збої або відсутні можливості.
Рішення: Якщо є невідповідність, перевстановіть драйвер чисто і перезавантажтесь. Не латайте розбіжність у драйверному стеку.
15) Виявити сигнали термального тротлінгу в системних сенсорах
cr0x@server:~$ sensors | sed -n '1,30p'
k10temp-pci-00c3
Adapter: PCI adapter
Tctl: +88.8°C
nvme-pci-0100
Adapter: PCI adapter
Composite: +73.9°C
Значення: Високі температури CPU і NVMe можуть непрямо впливати на GPU-ворклоади (тротлінг CPU, тротлінг I/O), навіть якщо сам GPU виглядає в порядку.
Рішення: Вирішіть питання обдування шасі та керування вентиляторами; сервер з GPU — це пристрій для керування теплом, який прикидається комп’ютером.
Жарт №2: Якщо ви не моніторите ширину PCIe-лінку, ваша оптимізація продуктивності — це по суті інтерпретативний танець з графіками.
План швидкої діагностики: що перевіряти в першу/другу/третю чергу
Коли хтось каже «GPU — вузьке місце», ваша задача — не стати людською кнопкою повторної спроби. Ось швидкий план, що допоможе швидко знайти реальні обмеження.
Першим: чи здорова платформа?
- Ширина/швидкість PCIe-лінку: перевірте на зниження. Якщо знижено — зупиніться і виправте апарат/прошивку/слотування.
- Логи ядра: шукайте скидання GPU, помилки AER, «fallen off the bus», зависання.
- Живлення і термали: перевірте, що частоти стабільні під навантаженням і живлення не обмежене несподівано.
Другим: чи «голодує» GPU від навантаження?
- Подача з CPU: профілюйте vkQueueSubmit / glDraw* накладні витрати і локи.
- Обмеження контейнерів: перевірте cgroup CPU і memory cap-и, що душать підготовку даних.
- Сховище та стрімінг активів: iowait і %util диска; завислий лоадер може виглядати як «переривчастий GPU».
Третім: чи обмежений GPU пам’яттю або плануванням?
- Тиск VRAM: майже повна VRAM + стуттер = ризик резидентного чату.
- Контенція мульти-орендарів: інші процеси займають VRAM або SM-час.
- Тротлінг живлення/температури: стійко низькі частоти попри попит.
Четвертим: тільки потім оптимізуйте шейдери/ядра
- Вимірюйте, чи ви обмежені обчисленнями або пам’яттю за допомогою профайлерів у вашому стеку.
- Зменшуйте overdraw, оптимізуйте шаблони доступу до пам’яті та налаштовуйте розміри батчів — після перевірки, що система вам не брешить.
Поширені помилки: симптоми → корінна причина → виправлення
Ось режими відмов, які повторюються, коли GPU «стає своїм світом» і команди забувають, що вони оперують двома системами, а не однією.
1) Симптом: низька утилізація GPU, але високий час кадру
Корінна причина: вузьке місце при подачі команд на CPU, вузькість при PCIe-передачах або синхронізаційні стаги.
Виправлення: Профілюйте CPU за допомогою perf, перевірте стан PCIe-лінку та огляньте fence/barrier-и. Батчіть роботи; зменшуйте накладні витрати per-draw; уникайте великих щокадрових передач.
2) Симптом: періодичні підвисання кожні кілька секунд
Корінна причина: вигнання/пейджинг VRAM, спайки стрімінгу текстур або фонова програма, що краде VRAM.
Виправлення: Зменшіть пікове використання VRAM, префетчіть, розбийте завантаження на частини, забезпечте ізоляцію GPU і явно бюджетуйте пам’ять, де API дозволяють.
3) Симптом: випадкові скидання GPU під навантаженням
Корінна причина: проблеми з подачею живлення, цілісністю сигналу PCIe, баги драйвера або перегрів.
Виправлення: Перевірте dmesg/journal на підписи скидань, тимчасово зменшіть power cap для тесту стабільності, переставте або замініть залізо і контролюйте розгортання драйверів.
4) Симптом: падіння продуктивності після «оновлення драйверів для швидкості»
Корінна причина: нова поведінка планувальника, інший компілятор шейдерів, регресія в управлінні пам’яттю.
Виправлення: A/B тестування з канарками, фіксація відомо-робочих версій і підтримка відтворюваних середовищ збірки/рантайму.
5) Симптом: працює на bare metal, ламається в контейнерах
Корінна причина: відсутні вузли пристроїв, неправильні runtime-hook-и, обмеження cgroup для пристроїв або невідповідність userspace/kernel драйверів.
Виправлення: Підтвердьте наявність /dev/nvidia* і права доступу, упевніться, що версії драйверів збігаються, і перегляньте конфігурацію runtime для GPU у контейнері.
6) Симптом: «Додали другу GPU і нічого не покращилось»
Корінна причина: робота не паралелізується, домінує синхронізація, накладні витрати на дуплікацію VRAM або подача команд CPU стає обмеженням.
Виправлення: Профілюйте масштабування. Якщо ви не можете розділити роботу — не купуйте складність. Віддавайте перевагу одному швидшому GPU або правильної паралельності завдань.
7) Симптом: раптовий обрив продуктивності після підвищення роздільності
Корінна причина: вибух по заповненню пікселями/overdraw, насичення пропускної здатності render target-ів або виснаження VRAM.
Виправлення: Зменшуйте overdraw, використовуйте більш ефективні формати, налаштовуйте AA/тіні і перевіряйте кількість та розмір render target-ів.
Чеклісти / покроковий план
Чекліст A: Підняття GPU-ноду як слід
- Перерахунок апаратного забезпечення: модель GPU, потужність PSU, план повітряного потоку шасі.
- Встановіть і зафіксуйте версію драйвера; зафіксуйте версію ядра і версії прошивок.
- Перевірте ширину/швидкість PCIe-лінку при завантаженні і після warm reboot.
- Запустіть стійкий тест навантаження і спостерігайте за потужністю, частотами, температуру та логами помилок.
- Налаштуйте алерти на скидання GPU, помилки AER і зниження лінку.
- Встановіть базові лінії: типовa утилізація, використання VRAM і пропускна здатність на ворклоад.
Чекліст B: Коли продуктивність «таємничо» гірша
- Підтвердіть, що нічого не змінилося: драйвер, ядро, прошивка, налаштування BIOS, runtime контейнера.
- Перевірте здоров’я платформи: стан PCIe-лінку і скориговані помилки.
- Перевірте стан GPU: термали, тротлінг, скидання.
- Перевірте обмеження CPU:
perf, ліміти cgroup, пересичення. - Перевірте тиск VRAM і інших орендарів GPU.
- Перевірте сховище/I/O, якщо залучений стрімінг.
- Лише потім: налаштуйте ядра/шейдери і стратегію батчінгу.
Чекліст C: Контроль змін у продакшн-стеку GPU
- Розгортайте оновлення драйверів по канарках з представницькими ворклоадами.
- Збирайте логи ядра і телеметрію GPU під час вікна канарки.
- Визначте тригери відкату: скидання, рівні помилок, регресії хвостової латентності.
- Розгортайте партіями; тримайте відому-робочу версію доступною.
- Документуйте очікування стану лінку (PCIe Gen і ширина) для кожної платформи.
Поширені питання (FAQ)
1) Що саме було «3D-акселератором» до терміну GPU?
Виділена плата, яка відвантажувала частини 3D-рендеринг-пайплайну — часто растеризацію, мапінг текстур і блендінг — тоді як CPU все ще робив значну геометричну роботу.
2) Чому раннє 3D-залізо віддавало перевагу фіксованому функціоналу?
Бо це давало передбачувану продуктивність на транзистор. Індустрія знала кроки пайплайну і могла запроектувати їх у чип для пропускної здатності та ефективності.
Програмованість з’явилась, коли фіксовані блоки перестали встигати за еволюцією технік рендерингу.
3) Чому VRAM має таке значення порівняно з системною RAM?
VRAM сконструйований для дуже високої пропускної здатності і широких інтерфейсів, що відповідають шаблонам доступу GPU. Системна RAM може бути швидкою, але перетин шини додає затримку і конкуренцію,
а запити GPU карають непередбачуваність.
4) Якщо утилізація GPU низька, чи можу я припустити, що GPU не є вузьким місцем?
Ні. Низька утилізація може означати голодування (подача з CPU, передачі PCIe, I/O), очікування синхронізації або проблему резидентності пам’яті.
Ставтеся до утилізації як до підказки, а не висновку.
5) Який найпоширеніший «прихований» вузький елемент GPU у продакшені?
Зниження або деградація продуктивності лінку PCIe через переговори або помилки. Це поширено, бо команди не фіксують стан лінку і не ставлять на нього алерти.
6) Чому драйвери GPU так часто фігурують у інцидентах?
Бо драйвер відповідає за величезний обсяг політик: управління пам’яттю, планування, компіляцію та сумісність.
Це також шар, який має адаптувати старі припущення до нового заліза, іноді в умовах сильного тиску по часу.
7) Який розумний підхід до мульти-тенантності на GPU?
Віддавайте перевагу жорсткій ізоляції: виділені GPU для кожного ворклоаду або апаратне партиціювання, якщо підтримується. Якщо ділити — моніторте споживання процесів,
встановлюйте квоти/бюджети і очікуйте контенції та хвостової латентності, якщо ворклоад не розроблений для шарінгу.
8) Як швидко відрізнити compute-bound від bandwidth-bound?
Почніть з телеметрії: споживана потужність і частоти (тиск обчислень) плюс використання VRAM і спостережувана пропускна здатність. Потім підтвердіть профайлингом:
якщо підвищення частот не допомагає, але зменшення трафіку пам’яті — допомагає, ви, ймовірно, bandwidth-bound.
9) Що змінилося з появою програмованих шейдерів?
GPU перестав бути набором фіксованих блоків і став масово-паралельним програмованим механізмом. Це відкрила нові можливості і перемістила складність:
компілятори, планування та переносимість продуктивності стали операційними аспектами.
10) Чому «GPU став окремим світом» важливо для SRE?
Бо тепер ви оперуєте двома різними системами з різними моделями ресурсів: CPU/RAM/сховище проти GPU/VRAM/PCIe/драйвер/прошивка.
Інциденти часто виникають на межі — там, де припущення помилкові і видимість погана.
Наступні кроки, які ви справді можете виконати
Якщо ви запускаєте GPU-ворклоади в продакшені — або збираєтеся — ставтесь до GPU як до підсистеми сховища або мережевого фрагмента: вимірювана, схильна до відмов і з власними уподобаннями.
Народження 3D-акселераторів навчило індустрію, що «графіка» — це пайплайн з власною фізикою. Сучасні GPU лише зробили цей пайплайн програмованим і простішим у неправильному використанні.
- Зробіть базовий моніторинг стану PCIe-лінку (швидкість і ширина) і ставте алерти на зміни.
- Збирайте логи ядра централізовано і індексуйте підписи скидань GPU і помилок AER.
- Бюджетуйте VRAM на ворклоад; вважайте майже повну VRAM ризиком надійності, а не знаком майстерності.
- Фіксуйте і розгортайте драйвери через канарки; вимірюйте хвостову латентність, а не лише середню пропускну здатність.
- Профілюйте подачу команд CPU перед тим, як чіпати GPU-ядра — бо морити GPU голодом — найпростіший спосіб виглядати «ефективним» на дашборді.
А потім зробіть те, чого більшість команд уникає: запишіть ваші припущення про світ GPU (пам’ять, планування, вартість передач) і протестуйте їх. У продакшені припущення — невпорядковані інциденти.