Інформація про візуалізацію, партії, графічну карту, продуктивність тощо + XNA?


12

Я знаю, що заголовок трохи розпливчастий, але важко описати, що я насправді шукаю, але ось що.

Що стосується рендерингу процесора, ефективність роботи, як правило, легко оцінити та зрозуміла, але коли мова йде про GPU через відсутність технічної довідкової інформації, я незрозумілий. Я використовую XNA, тому було б добре, якби теорія могла бути пов’язана з цим.

Отже, що я насправді хочу знати, що відбувається, коли і де (CPU / GPU), коли ви робите конкретні дії з малювання? Що таке партія? Який вплив мають ефекти, прогнози тощо? Чи зберігаються дані на відеокарті чи передаються на кожному кроці? Коли ви говорите про пропускну здатність, ви говорите про внутрішню пропускну здатність відеокарти або про конвеєр від процесора до GPU?
Примітка: Я насправді не шукаю інформації про те, як відбувається процес малювання, це справа GPU, мене цікавлять усі накладні витрати, які передують цьому.

Я хотів би зрозуміти, що відбувається під час дії X, щоб адаптувати свої архітектури та практики до цього.

Будь-які ціни (будь-які статті (можливо, з прикладами коду)), інформація, посилання, навчальні посібники, які дають більше розуміння того, як писати кращі ігри, дуже вдячні. Дякую :)


2
Хоча це спочатку XNA, я додав тег DirectX, оскільки це основна технологія - це може допомогти вам отримати кращі відповіді. Також ознайомтеся з цією відповіддю, яка може дати вам хороший вихідний пункт
Ендрю Рассел

@AndrewRussell Дякую велике :). Я фактично вже читав різні статті з цієї теми, включаючи цю. Але це не охопило все, що я хотів би знати.
Айдіакапі

Відповіді:


20

Мені подобається думати про ефективність з точки зору " меж ". Це зручний спосіб концептуалізації досить складної взаємопов’язаної системи. Коли у вас є проблеми з продуктивністю, ви задаєте питання: "В які межі я потрапляю?" (Або: "Я пов'язаний CPU / GPU?")

Ви можете розбити його на кілька рівнів. На найвищому рівні у вас є процесор і GPU. Ви можете бути прив'язаними до процесора (GPU сидіти в режимі очікування, що чекає CPU) або GPU (CPU очікує на GPU). Ось хороша публікація в темі.

Ви можете розбити його далі. На стороні процесора ви можете використовувати всі свої цикли на даних, які вже є в кеші CPU. Або у вас може бути обмежено пам'ять , залишаючи процесор очікувати, коли дані надійдуть з основної пам'яті ( так оптимізуйте макет даних ). Ви можете все-таки розбити його.

(Хоча я роблю широкий огляд продуктивності щодо XNA, я зазначу, що виділення еталонного типу ( classне struct), хоча це зазвичай дешево, може викликати збирач сміття, який спалить багато циклів - особливо на Xbox 360 . Дивіться тут для більш докладної інформації).

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

Простіше кажучи, деякі з великих є: " ліміт заповнення " (скільки пікселів ви можете записати в backbuffer - часто скільки ви можете перевищити ), " limit shader " (наскільки складними можуть бути ваші шейдери та скільки даних ви можете просунути через них), " обмеження пропускної здатності текстури / пропускної здатності текстури " (скільки текстурних даних ви можете отримати доступ).

І ось тепер ми підійшли до великого - про що ви справді запитуєте - де процесор і GPU мають взаємодіяти (через різні API та драйвери). Нещільно є " пакетна межа " та " пропускна здатність ". (Зауважте, частина першої серії, про яку я згадував раніше, детально описується.)

Але, в основному, пакет ( як ви вже знаєте ) відбувається, коли ви викликаєте одну з GraphicsDevice.Draw*функцій (або частина XNA, як-от SpriteBatch, робить це за вас). Як ви, без сумніву, вже прочитали, ви отримуєте кілька тисяч * з них за кадр. Це обмеження для процесора - тому воно конкурує з вашим іншим використанням процесора. Це в основному драйвер, який упаковує все про те, що ви сказали йому намалювати, і відправивши його в GPU.

А далі є пропускна здатність до GPU. Це стільки необроблених даних, які ви можете передати туди. Сюди входить вся інформація про стан, яка постачається з партіями - все, від встановлення констант / параметрів стану та шейдерних констант / параметрів (що включає такі речі, як матриці світ / погляд / проект), до вершин при використанні DrawUser*функцій. Він також включає будь-які дзвінки до SetDataта GetDataна текстурах, вершинні буфери тощо.

На цьому етапі слід сказати, що все, на що можна закликати SetData(текстури, вершинні та індексні буфери тощо), а також Effects - залишається в пам'яті GPU. Він не постійно надсилається до GPU. Команда малювання, яка посилається на ці дані, просто надсилається вказівником на ці дані.

(Також: ви можете надсилати команди малювання лише з основного потоку, але ви можете SetDataз будь-якого потоку.)

XNA ускладнює речі кілька з його роблять державні класи ( BlendState, DepthStencilStateі т.д.). Цей стан дані будуть відправлений за виклик відтворення (в кожній партії). Я не на 100% впевнений, але перебуваю під враженням, що він відправлений ліниво (він лише надсилає стан, який змінюється). Так чи інакше, зміни в державі дешеві до точки вільного, відносно вартості партії.

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

Два особливих випадки, на які слід стежити, - це дзвінок GetDataна будь-що динамічне, особливо на RenderTarget2Dте, на що може писати GPU. Це надзвичайно погано для продуктивності - не робіть цього.

Інший випадок викликає SetDataвершинні / індексні буфери. Якщо вам потрібно часто це робити, використовуйте DynamicVertexBuffer(також DynamicIndexBuffer). Вони дозволяють GPU знати, що вони часто змінюватимуться, і робити якусь магію буферизації всередині, щоб уникнути вимивання трубопроводу.

(Також зауважте, що динамічні буфери швидші, ніж DrawUser*методи, але їх потрібно попередньо виділити за максимально необхідним розміром.)

... І це майже все, що я знаю про продуктивність XNA :)


Дуже тобі вдячний! Це саме те , що я шукав і сподівався :).
Айдіакапі

1
Кілька сотень партій на кадр звучать занадто песимістично. Я завжди чув, як правило, від 2 до 3 К партій на кадр. Як відомо, деякі ігри на ПК набирають до 10 К, але я думаю, що для цього потрібна велика обережність.
Натан Рід

Абсолютно вірно. Цифра "кілька сотень" походить з паперу "Пакетна партія", в якій перераховано "25k партій / с @ 100% процесора 1 ГГц". Але цьому документу вже десять років, і драйвери та процесори значно покращилися відтоді. Я оновлю це (і мої інші), щоб прочитати "кілька тисяч".
Ендрю Рассел
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.