Чому безпека потоків така величезна угода для графічних API?


21

Як Vulkan, так і DirectX12, як стверджується, є зручними для використання в потоці. Люди, здається, схвильовані з цього приводу.

Чому це вважається такою величезною особливістю? "Справжня" обробка все одно перекидається через міст пам'яті на окремий процесор.

Крім того, якщо він настільки великий, то чому до цього часу не вийшов безпечний для потоків графічний API?


Ця стаття набагато більш "орієнтована на геймер", але вона може дати вам деяку інформацію ... pcgamer.com/what-directx-12-means-for-gamers-and-developers
glampert

Відповіді:


13

Основним виграшем було б те, що було б простіше розділити завдання CPU на кілька потоків, не потребуючи вирішення всіх складних проблем з доступом до графічного API. Зазвичай вам або доведеться зробити контекст поточним (що може мати негативні наслідки для продуктивності) або надати чергу і викликати графічний api в один потік. Я не думаю, що будь-яка продуктивність отримується таким чином, оскільки GPU дійсно обробляє їх послідовно, але це значно спрощує роботу розробника.

Причиною того, що це не було зроблено дотепер, ймовірно, є те, що directx та opengl були створені в той час, коли багатопотокове читання насправді не було очевидним. Також рада «Хронос» дуже консервативна у зміні API. Їхня думка щодо Вулкана також полягає в тому, що він буде співіснувати поряд з OpenGL, оскільки обидва служать різним цілям. Мабуть, не так недавно паралізм став таким важливим, оскільки споживачі отримують доступ до все більшої кількості процесорів.

EDIT: Я не маю на увазі, що від виконання роботи в декількох процесорах не отримується ніякої продуктивності, не корисно розділяти виклики на кілька потоків, щоб швидше створювати текстури / шейдери. Швидше за все, продуктивність отримується завдяки тому, що більше процесорів зайнято та підтримує gpu зайнятим справами.


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

9

Процесору потрібно багато роботи, щоб створити кадр для GPU, і хороший фрагмент цієї роботи знаходиться всередині драйвера графіки. До DX12 / Vulkan, дизайн графічних драйверів по суті був змушений бути однопоточним дизайном API.

Сподіваємось, що DX12 / Vulkan скасує це обмеження, що дозволяє працювати водіям паралельно на декількох потоках процесора в рамках. Це дасть змогу ефективніше використовувати багатоядерні процесори, дозволяючи ігровим двигунам відтісняти складніші сцени, не стаючи процесором. Ось надія - чи реалізується це на практиці - це те, що нам доведеться чекати, щоб побачити протягом наступних кількох років.

Щоб трохи уточнити: вихід рендерера ігрового двигуна - це потік викликів API DX / GL, що описують послідовність операцій з візуалізації кадру. Однак існує велика відстань між потоком викликів API та фактичними бінарними командними буферами, які споживає апаратне забезпечення GPU. Драйвер повинен "компілювати" виклики API на машинну мову графічного процесора, так би мовити. Це не тривіальний процес - він включає багато перекладу концепцій API в апаратні реалії низького рівня, перевірку, щоб переконатися, що графічний процесор ніколи не встановлюється в недійсний стан, невмілий розподіл пам'яті та даних, відстеження змін стану для видачі проблеми виправляти команди низького рівня тощо. Графічний драйвер відповідає за все це.

У API DX11 / GL4 та більш ранніх версіях ця робота, як правило, виконується одним потоком драйвера. Навіть якщо ви зателефонуєте API з декількох потоків (що, наприклад, ви можете зробити за допомогою відкладених списків команд DX11), він просто додає певної роботи до черги, щоб нитка драйвера переглядати пізніше. Однією з великих причин цього є відстеження стану, про яке я згадував раніше. Багато деталей конфігурації графічного процесора на апаратному рівні вимагають знання поточного стану графічного конвеєра, тому немає хорошого способу розбити список команд на шматки, які можна обробляти паралельно - кожен фрагмент повинен точно знати, у якому стані він повинен починатися. , хоча попередній фрагмент ще не оброблений.

Це одна з великих речей, яка змінилася в DX12 / Vulkan. З одного боку, вони включають майже весь стан графічного конвеєра в один об'єкт, а для іншого (принаймні, у DX12), коли ви починаєте створювати список команд, ви повинні надати початковий стан конвеєра; стан не успадковується від одного списку команд до іншого. В принципі, це дозволяє водієві нічого не знати про попередні списки команд, перш ніж він може почати компілювати - а це, в свою чергу, дозволяє додатку розбивати його візуалізацію на паралелізуючі фрагменти, створюючи повністю складені списки команд, які потім можуть бути об'єдналися разом і направлялися до GPU з мінімальним метушнею.

Звичайно, в нових API є багато інших змін, але що стосується багатопотокової роботи, це найважливіша частина.


5

Сучасні графічні процесори, як правило, мають єдиний фронтальний розділ, який обробляє повністю лінійний потік команд з процесора. Незалежно від того, чи це натуральна апаратна конструкція, чи вона просто розвинулася з тих часів, коли існувало єдине ядро ​​CPU, що генерує команди для графічного процесора, дискусійне, але наразі це реальність. Отже, якщо ви генеруєте єдиний лінійний потік стаціонарних команд, звичайно, має сенс генерувати цей потік лінійно на одному потоці процесора! Правильно?

Ну, а сучасні графічні процесори, як правило, мають дуже гнучкий уніфікований сервер, який може працювати відразу над багатьма різними речами. Взагалі, GPU працює над вершинами та пікселями з досить тонкою деталізацією. Існує не велика різниця між GPU, що обробляє 1024 вершини в одному малюнку, і 512 + 512 вершин у двох різних малюнках.

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

На жаль, у сучасній графічній графічній реальності API дзвінки дзвінків надзвичайно дорогі на процесорі. Спрощене пояснення того, чому: зміни стану на графічному процесорі можуть не відповідати безпосередньо викликам графічного API, тому багато викликів графічного API просто встановлюють деякий стан всередині драйвера, і виклик виклику, який залежатиме від цього нового стану, йде і дивиться на всі стан, який позначений як змінений з моменту останнього малювання, записує його в командний потік для GPU, а потім фактично ініціює малюнок. Це вся робота, яка робиться в спробі отримати слабкий і середній потік команд для фронтального блоку GPU.

Це зводиться до того, що у вас є бюджет на дзвінки, які повністю накладаються накладні витрати водія . (Я думаю, що я чув, що в ці дні ви можете отримати близько 5000 за кадр за 60 FPS-заголовок.) Ви можете збільшити це на великий відсоток, будуючи цей командний потік паралельно відрізками.

Є й інші причини (наприклад, асинхронний затримка для покращення затримки VR), але це велика графіка для ігор, пов'язаних з графікою та іншого важкого програмного забезпечення, наприклад, для моделювання 3D-моделей.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.