понедельник, 7 февраля 2022 г.

В чем проблема Vulkan on top of Metal

 MoltenVk и некоторые другие проекты предоставляют возможность использовать Vulkan API поверх Apple Metal API, но внутри они содержат много неэффективного кода.


Чем отличается Metal от Vulkan

  • Vulkan это низкоуровневое API, а Metal более высокоуровневое, при этом по функционалу они мало отличаются.
  • Metal 2 разработан чтобы максимально использовать возможности новых iPhone и M1.
  • Metal внутри себя уже содержит frame graph, а для Vulkan надо писать свой FG поверх него. По этой причине в Metal используются пассы (render, compute, blit и тд), эти пассы могут выполняться в любом порядке, как решит FG.
  • В Vulkan замер времени может сломать распараллеливание команд (например компьют команд), в Metal для iPhone и M1 замер времени работает только для пассов, это так же связано с перестановкой пассов так как невозможно правильно замерить время группы пассов, потому что они могут выполняться в разном порядке и параллельно. То есть правильнй замер времени на Metal это замерить время начала и конца каждого пасса в группе, а потом найти минимум и максимум. Зато в Metal замер времени никак не влияет на распараллеливание команд внутри пасса и на перестановку и параллельное выполнение пассов.
  • В Metal поддерживаются новый фичи - tile shader, ray tracing, rasterization order. Часть имеет аналоги в vulkan или расширения находятся в разработке.
  • В Vulkan есть поддержка fragment_shading_rate и fragment_density_map, которые существенно отличаются от аналога в Metal - rasteriazation rate map, из-за чего невозможно (или очень сложно) сделать поддержку фичи из Metal в Vulkan.

В чем проблема MoltenVk

  • MoltenVk написан так, чтобы проходить Conformance Tests, как раз с этим связана часть неэффективности.
  • В Vulkan для мобильных GPU эффективнее использовать рендер пассы с сабпассами, а в MoltenVk сабпассы реализованы как отдельные рендер пассы в Metal из-за чего кэш тайла не используется, это очень неоптимально.
  • В дополнение к предыдущему пункту - неправильно работает lazy allocated memory - память выделяется только в кэше тайла, так как идет сохранение в глобальную память, то содержимое такой текстуры теряется.
  • Для десктопов в MoltenVk используется массив ресурсов с host visible памятью. При сабмите команд на GPU требуется сделать все изменения на строне CPU видимыми на GPU, поэтому идет проход по массиву и флушатся все изменения. Для iPhone этот код не выполняется так как там общая память, а вот для M1 исключение не сделано. (Возможно это уже оптимизированно).
  • Async compute на Metal в некоторых случаях дает прирост производительности, а что-то внутри MoltenVk никак не позволяет получит выигрышь от нескольких очередей и чаще всего даже замедляет рендер.

Как было бы правильно

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

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

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