Новости 20.08.2017 Автор: RPCS Team 88 0

ОБРАБОТКА VERTEX И ПРИРОСТ ПРОИЗВОДИТЕЛЬНОСТИ

Я - kd-11, графический разработчик rpcs3 с обновлением в середине месяца о последних достижениях эмулятора.

Поскольку многие уже знают, многое начало запускаться в последнее время с новыми изменениями в RSX (PS3 GPU) на эмуляцию, дублирована перезапись Vertex`ов. Это изменение перемещает много режимов работы обработки Vertex`ов от ЦП в GPU, где они должны находится и в результате есть крупное увеличение производительности особенно с OpenGL, но также и с Vulkan в геометрии c тяжелыми сценами.

Фон
Большинство, если не все пользователи, вероятно, знают об этом, но выделенные графические карты существуют на физически отдельной плате. Это означает, что данные должны быть перемещены в и из него через шину PCI-E, что довольно быстро. Однако, хотя это высокая пропускная способность, она также обладает высокой задержкой. Это означает, что вы не можете просто отправить что-то туда и ожидать, чтобы он был немедленно доступен для следующего вызова. Вместо этого графический процессор должен ждать, пока данные будут подготовлены, а затем сообщит, что данные готовы к обработке до начала работы. Это общее упрощение, но это помогает проиллюстрировать суть. Однако RSX на PS3 работает не так. Он имеет непосредственный доступ к основной памяти XDR на PS3 и «вытаскивает» данные непосредственно из основной памяти, как если бы это была локальная память. В этом случае он похож на интегрированную графическую память. Это означает, что данные не «предварительно упакованы» для транспортировки на графический процессор PS3, поскольку память практически унифицирована с точки зрения RSX. При использовании Vulkan прорисовка не планируется до тех пор, пока вся командная очередь не будет сброшена, чтобы смягчить влияние переноса, поскольку данные, вероятно, будут загружены заранее, но для OpenGL это было большим узким местом.

Вторая проблема заключалась в том, что эмулятор делал много вычислений на CPU о том, как читать данные Vertex`ов из основной памяти, по существу предварительно упаковывая данные в форматы, которые легко использовать для использования графическими процессорами. Это очень медленный процесс, а также очень затратный по объему памяти (следовательно, сбой «рабочего буфера недостаточно»). Включение отладочного наложения со старым методом показывает, что некоторые игры занимают до 200 мс для подготовки данных Vertex`ов для одного кадра (Hellboy: The Science of Evil). Это, очевидно, не оптимально. Влияние может быть снижено за счет использования большего количества потоков для обработки Vertex`ов, но с количеством потоков, которые уже были необходимы для эмуляции многоядерного процессора PS3, это было проблемой. Истечение 8+ потоков обработки Vertex`ов уменьшило время обработки обработанных Vertex`ов, но стоимость других потоков для голодания и производительности значительно снизится. Решение заключалось в том, чтобы перенести работу на GPU и не трогать ее каким-либо образом. Просто скопируйте блок данных, и графический процессор может извлечь нужные ему данные, имитируя поведение реального оборудования.

Первоначальные тесты
Первой задачей было проверить эту теорию. Я начал с написания подпрограмм, чтобы идентифицировать непрерывную память, используемую играми, для хранения данных Vertex`ов и наиболее часто используемого чередования, чтобы ускорить передачу данных даже на реальном ps3. Это хорошо, так как копирование очень простое, сжимая до одной операции memcpy. Я быстро проверил OpenGL, чтобы использовать этот метод всякий раз, когда были использованы большие блоки данных, и запустил тестовый пример, который я использовал некоторое время для тестирования обработки Vertex`ов - экран заголовка ТНТ. Сцена очень проста, но отрисовывает Vertex`ы, используя прямую прорисовку и делает более 2000 отрисовок. Это была проблема на rpcs3, где OpenGL застрял на скорости 10 кадров в секунду в течение длительного времени. Используя упрощенную обработку, FPS поднялся примерно до 17, поэтому эксперимент прошел успешно. Время загрузки Vertex значительно сократилось примерно с 50 мс на фрейм до менее 10 мс. Однако изменение частоты кадров было не столь впечатляющим, поэтому мне пришлось провести еще несколько исследований.

Исследования и вторая попытка
После получения ответа от ssshadow, что повышение производительности было не таким, как ожидалось, я попытался выяснить, как драйверы обрабатывают записи памяти на внешние устройства PCI-E. Для этого я обратился к драйверам с открытым исходным кодом mesa, которые я использую на своем ПК и вылил через код. Я подтвердил использование памяти с записью для повышения пропускной способности и начал работу по перепроектированию конвертера рендеринга, чтобы эффективно использовать это. Упрощенная одиночная запись в маленький непрерывный блок уже дала хороший импульс, поэтому я попытался переупорядочить, где была высокая Vertex`ная загрузка, чтобы дать ей некоторое время до вызова отрисовки, требующего, чтобы данные были выгружены. Запись в память была размещена очень рано в цепочке отправки, а другие вычисления перемещались после этой точки, но до вызова отрисовки. Таким образом, GPU может получить данные до того, как это понадобится, повысив эффективность рендеринга. С этим изменением я установил предел GPU на уровне ~ 25 кадров в секунду, что на 2,5 раза выше первоначального результата теста и 10 кадров в секунду по сравнению с первоначальной реализацией. Обновление драйвера позже привело к скорости кадров до ~ 28 кадров в секунду, но это там, где мое оборудование было отключено.

Vulkan и разочаровывающие результаты
После того, как исследование было завершено, у меня было хорошее представление о том, что делать, чтобы максимизировать пропускную способность на Вулкане. Я быстро применил изменения к Vulkan и реорганизовал общий код между рендерерами, чтобы упростить будущую работу. Я быстро провел тот же тест на Vulkan, ожидая 30 кадров в секунду, но только получил +1 к fps; От 14 кадров в секунду до 15 кадров в секунду. После измерения времени, проведенного в разных частях канала, я нашел еще одно узкое место, которое удерживало Vulkan в течение самого долгого времени. Каждый кадр ожидал завершения предыдущего кадра до начала рендеринга. Это не очень эффективное использование графического оборудования или API. Поскольку базовый фреймбуфер использует настройку двойного буфера, есть две поверхности для записи. Нет необходимости ждать предыдущих команд, если они записываются на другую поверхность. Быстрая реструктуризация позже и рендеринг были переписаны для поддержки асинхронной обработки кадров.

Финальные результаты
Объединение двух оптимизаций и запуск одного и того же теста дали около 24 кадров в секунду. Это было примерно на 10 fps выше, чем базовая производительность, предоставляемая в master релизе. Я запустил еще один тест - Hellboy: Science of Evil и подтвердил, что fps прыгнул с 3-5 кадров в секунду до 20-30 кадров в секунду на OpenGL и Vulkan. В противоположность этому, поведение доступа к памяти в интегрированной графике Intel дает 40 кадров в секунду на этой сцене с использованием новых бэкэндов OpenGL, что почти вдвое превышает производительность Vulkan в 270 раз. Это показывает, что с большей оптимизацией все может быть лучше.

Другим побочным эффектом унификации обработки Vertex`ов и правильной обработки было то, что многие игры, у которых не было визуального результата, сразу начали работать. Наиболее заметными случаями здесь являются Metal Gear Solid 2 и Metal Gear Solid 3. Shadow of the Colossus также частично исправлена, а также улучшения в других играх, таких как «Sleeping Dogs» и «Yakuza».

Были добавлены и другие исправления, которые исправили графику Ni No Kuni при использовании Vulkan, а также сломанную глубину в этом названии. Игры на Unreal engine 3 также искажали цвет в интро-кинематике и логотипы, которые также были исправлены.

Все выглядело хорошо, но возникла еще одна проблема - компилятор шейдеров зависал делая геймплей невыносимым.

Баги и технические вопросы
Несмотря на то, что набор изменений значительно улучшает базовый канал с новыми системами, он приносит с собой новые проблемы. Во-первых, это увеличение времени компиляции шейдеров. Вторая более серьезная проблема более актуальна для пользователей nvidia - высокая загрузка памяти при увеличении числа предварительно скомпилированных шейдеров. Эта проблема была доведена до моего сведения пользователем о разладке, который упомянул, что Cemu работает одинаково, и что пользователи nvidia испытывают ту же проблему, что и при использовании большого количества оперативной памяти. На rpcs3 это означает, что вы можете увидеть, как эмулятор потребляет 5 ГБ ОЗУ при компиляции шейдеров. Временным решением для тех, кто имеет более низкую ОЗУ, было бы очищать кеш шейдера периодически, пока мы не найдем подходящее обходное решение.

Что это значит?
Во-первых, это означает, что OpenGL теперь находится в удалении от Vulkan с точки зрения производительности и быстрее в некоторых случаях. Vulkan, однако, страдает от первого зашифрования шейдерной компиляции. Это будет улучшено в ближайшем будущем, но на данный момент вы можете попробовать OpenGL, если зависание слишком отвлекает. В целом Vulkan все еще быстрее с переработанной инфраструктурой. Я видел предложения об отключении кэша шейдеров - это не поможет с зависанием, поскольку он вызван шагом соединения, который выполняется драйверами. Я бы попросил тех, кто отрицательно пострадал, быть немного более терпеливым, поскольку мы работаем над решением проблем.
скачать dle 11.3

Популярные новости
Новые статьи