четверг, 14 июля 2022 г.

Нужен ли рендер граф? Часть 2

 Теоретизираю какой бы идеальный рендер граф я бы написал.

Экономика

На написание идеального рендер графа уйдет много месяцев, а может и несколько лет, стоит ли оно того? В первой части я доказывал, что рендер граф не нужен, теперь придется доказать, что он может быть экономически выгоден.

Чтобы максимально оптимизировать конечный продукт нужен кто-то, кто хорошо разбирается в архитектуре GPU, умеет пользоваться профайлером и знает как применять результаты замеров. Причем у каждого производителя свои профайлеры и особенности работы GPU, что также усложняет задачу. Рендер граф может содержать все эти знания в виде алгоритма и применять их для оптимизации рисования кадра, сэкономив при этом время на поиск специалиста и на оплате.

С другой стороны рендер граф это всего лишь один из компонентов движка и еще меньший компонент от конечного продукта, он может ускорить рисование на 10-20% или даже на 50% если используются асинхронные очереди, которые позволят распараллелить работу. Но рендер граф не даст никакого выигрыша, если код уже написан идеально.

Самая важная оптимизация, это выбор правильного алгоритма (forward+, deferred, visibility buffer, ray tracing и тд) и оптимизация контента. Далее идет оптимизация шейдеров и только после всего этого идет оптимизация синхронизаций и улучшение распараллеливания. Если уже было затрачено время на подобные оптимизации, то экономить на ручной оптимизации синхронизаций не имеет смысла, следовательно и рендер граф не нужен.

Остается вариант, когда есть движок с хорошо оптимизированными алгоритмами и шейдерами, но при этом позволяющий пользователям самим настраивать проходы рендеринга, что исключает возможность ручной оптимизации синхронизаций на стороне разработчиков движка, вот здесь рендер граф необходим и экономически оправдан.

Оптимизация синхронизаций и перестановка проходов

Так как это идеальный рендер граф, то все недостатки из первой части здесь отбрасываются. Рендер граф имеет доступ к хардварным счетчикам от вендоров и способен накапливать информацию о каждом прохоже, чтобы понять, во что упирается производительность. Далее рендер граф распределяет проходы по очередям, так чтобы добиться максимальной эффективности. Это некий аналог profile guided optimization (PGO) у компилятора.

Внутри одной очереди также происходят перестановки, чтобы минимизировать простои GPU. Переставляются не только группы команд - проходы (RG pass), но и команды внутри них, если между ними есть зависимости, например если это вызовы компьют шейдера.

Пример перестановки команд: есть ландшафт, состоящий и тайлов, за один кадр можно обновить X тайлов, для каждого тайла сначала генерируется карта высот, потом карта нормалей, биомы и тд, между каждым проходом ставится барьер. Но это не эффективно, поэтому рендер граф может переставить команды, чтобы сначала вызвались все команды генерации карты высот, потом генерация нормалей и тд. Да, это можно было настроить руками, а можно было вынести в один компьют шейдер и использовать кэш для временного хранения данных, что было бы быстрее, но предполагается, что рендер граф будут использовать не самые сильные программисты, которые не додумаются до такой оптимизации.

Процессоры могут делать подобные оптимизации на уровне инструкций, но на более высоких уровнях у них нехватает размера "окна" для чтения последующих инструкций, поэтому программистам приходится делать такие оптимизации вручную или автоматизировать их неким образом.

Возможно в дальнейшем драйвера или ОС будут содержать свой граф проходов/тасков, который будет выпоняться наилучшим образом. Например в Metal уже есть рендер граф, но из-за этого существует ограничение на однопоточное использование API.

Комментариев нет:

Отправить комментарий