[Перевод] Apple M1 хорош, но насколько он хорош в трассировке лучей?

[Перевод] Apple M1 хорош, но насколько он хорош в трассировке лучей?

Чип Apple M1, установленный в новых MacBook Air, MacBook Pro и Mac Mini, уже стал предметом множества обсуждений, статей о бенчмарках и публикаций в блогах. Скорость и производительность его действительно впечатляют, особенно касаемо производительности на ватт.

Но конкретно сейчас мы остановимся подробнее на трассировке лучей — в частности, на трассировке лучей через API Metal, анонсированный на WWDC-2020.

Для тестов в данной статье использовались Mac Mini и интерактивный трассировщик пути ChameleonRT, а сравнение проводилось с DirectX, Vulkan, OptiX и Embree.

Подробнее о ChameleonRT

ChameleonRT — интерактивный трассировщик пути с открытым исходным кодом, созданный для изучения различных API трассировки лучей. Он предоставляет бэкэнд для таких API, как DirectX Ray Tracing, Vulkan KHR Ray Tracing и OptiX 7, а теперь и Metal. Также он поддерживает бэкэнд Embree для быстрой многопоточной и ускоренной с помощью SIMD трассировки лучей на ЦП через Embree, ISPC и TBB. Код рендеринга в каждом случае практически идентичен. На выходе получаются пиксельные данные с возможными небольшими различиями, связанными с различиями в библиотеках трассировки лучей и языках шейдеров.

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

ChameleonRT — их полная противоположность, поддерживающая только один тип геометрии — треугольные мэши — и один тип материала – Disney BRDF. Остальной код написан в целом аналогично другим бенчмаркам для достижения производительной интерактивной трассировки пути, но в то же время так, чтобы его было довольно просто читать. Например, рендереры здесь используют итеративную трассировку лучей вместо рекурсивной, а также только простую стратегию сэмплинга, и не поддерживают эффекты cutout. Использование итеративной трассировки лучей полезно как для ЦП, так и для ГП, хотя для последнего особенно важно — ведь нагрузки при вызове программной рекурсивной трассировки лучей могут существенно повлиять на производительность. Точно так же игнорирование cutout эффектов позволяет рендерерам ГП пропускать использование hit-шейдеров. Они будут вызваны уже во время обхода BVH после нахождения пересечения с треугольником. Аппаратное ускорение обхода BVH приводит к возникновению большого количества возвратов между фиксированной функцией обхода BVH и ядрами для запуска hit-шейдера, что ограничивает производительность оборудования.

Что такое трассировщик пути? Трассировка пути — это метод рендеринга фотореалистичных изображений путем симуляции переноса света в сцене. Это метод Монте-Карло, случайным образом выбирающий пути прохождения света, попадающего в камеру, отражаясь от объектов в сцене. Он реализуется посредством отслеживания пути в направлении от камеры обратно через всю сцену. Для получения изображения без шума необходимо выполнить сэмплинг большого количества световых путей. Трассировка пути не ограничивается применением только в фотореалистичный изображениях. Она также широко используется в кинорендерерах, таких как Renderman от Pixar, Hyperion от Disney, Arnold от Autodesk и Manuka от Weta.

Трассировка лучей на ГП через Metal

Трассировка лучей в новом Metal API похожа на встроенную трассировку лучей в DirectX или Vulkan. Чтобы узнать подробнее, что представляет из себя Metal, можно посмотреть видео с WWDC 2020 и ознакомиться с этим кодом. Встроенная поддержка трассировки лучей позволяет приложениям выполнять вызовы трассировки лучей в шейдерах на любом этапе — например, в шейдерах фрагментов/пикселей, вершинных шейдерах, вычислительных шейдерах и т. д. Также она позволяет включать эффекты трассировки лучей — например, точные отражения и тени — в стандартный пайплайн растеризации. Ее можно использовать в вычислительном шейдере для реализации автономного рендерера на основе трассировки пути. ChameleonRT — автономный трассировщик путей, использующий подход вычислительных шейдеров для Metal.

Трассировка лучей в Metal выполняется следующим образом: вы загружаете свою геометрию, строите над ней примитивные структуры ускорения нижнего уровня, затем создаете инстансы, ссылающиеся на эти структуры, и строите структуру ускорения верхнего уровня поверх этих инстансов. Для рендеринга сцены нужно запустить вычислительный шейдер и непосредственно рейкасты в структуру ускорения верхнего уровня, чтобы получить возвраты от ее пересечений с лучами. Результаты пересечения несут данные о пересекающихся примитивах и геометрии, а при использовании инстансов — и об инстансах. Затем ваш шейдер ищет геометрические данные об объекте, в который попал рейкаст, и закрашивает его, после чего можно продолжить процесс трассировки пути.

В настоящее время Metal поддерживает только встроенную трассировку лучей, в отличие от DirectX и Vulkan, которые также обеспечивают поддержку программной трассировки. Она, в свою очередь, используется для реализации автономных средств рендеринга трассировки лучей — именно этот подход ChameleonRT использует в DirectX и Vulkan. OptiX поддерживает только программную трассировку лучей, что требует создания таблицы привязки шейдеров (Shader Binding Table, SBT) для предоставления API таблицы функций, вызываемых при пересечении определенных объектов в сцене. SBT трудно настраивать и отлаживать, однако их потенциальное преимущество в том, что так графический процессор получает возможность переупорядочивать и группировать вызовы функций для уменьшения расхождения потоков. При встроенной трассировке лучей разработчику необходимо произвести все это вручную или вовсе от этого отказаться (подробнее см. другое видео с WWDC20).

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

Трассировка лучей в Metal во многом похожа на другие API, но оптимизирована для более простого использования. Например, для сравнения приведем код, необходимый для сборки и сжатия BVH в DirectX или Vulkan и Metal. API OptiX обеспечивает аналогичное упрощение — вот ссылка на сборку BVH в OptiX в качестве примера. Также приятным бонусом идет возможность иметь шаблоны и функциональные возможности стилей C++ в языке шейдеров — это функция Metal, использующая CUDA для кода на стороне устройства.

Однако в этой простоте есть и свои недостатки. Например, в то время как в DirectX, Vulkan и OptiX вы можете контролировать, где выделяется память для структуры ускорения, Metal вам не оставляет никакого выбора. В результате вы не можете выделить структуры ускорения в MTLHeap и поэтому, чтобы убедиться, что они доступны для вашего пайплайна рендеринга, вы должны сами пометить их как используемые в цикле — вместо простого вызова useHeap.

// Использование структуры ускорение верхнего уровня

[command_encoder setAccelerationStructure:bvh->bvh atBufferIndex:1];

// Помечаем все структуры ускорения мэшей как используемые

for (auto &mesh : bvh->meshes) {

    [command_encoder useResource:mesh->bvh usage:MTLResourceUsageRead];

}

Если у вас много BVH нижнего уровня, как это бывает в сценах с большим количеством инстансов, могут возникнуть дополнительные нагрузки. Было бы неплохо иметь возможность выделить структуры ускорения в куче и заменить этот цикл одним [commandencoder useHeap: dataheap-> heap];

Этот API также значительно упрощается за счет того, что он не включает программную трассировку лучей и требует только структуру в виде таблицы привязки шейдеров при реализации настраиваемых геометрий или других операций, которые должны выполняться во время обхода (например, cutout). Код для управления настройкой SBT в DirectX, Vulkan и OptiX составляет значительную часть вспомогательного кода в бэкэнде для каждого API, и хорошо, что этого нет в Metal, не работающем с настраиваемой геометрией или cutout текстурами. Однако в модели SBT графический процессор может группировать или переупорядочивать вызовы функций, но это меньше касается встроенной трассировки лучей, в случае которой такая информация недоступна для драйвера. Действительно ли текущие драйверы для DirectX, Vulkan и OptiX на это способны – вопрос к разработчикам, но теоретически это возможно. В конце концов, вы можете обнаружить, что реализуете что-то вроде более простого аналога SBT для поиска необходимых данных о примитивах/мэшах/инстансах в вашей сцене в буферах аргументов, как это реализовано в ChameleonRT. Тогда же вам необходимо реализовать операции, происходящие во время обхода (настраиваемая геометрия, прозрачность cutout).

Быстрая трассировка лучей на ЦП с библиотеками Intel

В результатах CineBench от AnandTech можно заметить, что CineBench использует Embree — библиотеку трассировки лучей на ЦП от Intel, обеспечивающую оптимизированный обход структуры ускорения и ядер пересечения примитивов, оказывая такую ​​же нагрузку на ЦП, что и новые API трассировки лучей на ГП. Embree была выпущена в 2011 году и с тех пор нашла широкое применение в кино, науке и других сферах.

ChameleonRT также поддерживает бэкэнд Embree, использующий Embree для быстрого обхода лучей и пересечения примитивов, ISPC — для программирования SIMD и TBB — для многопоточности. На самом деле, запустить его на M1 Arm довольно просто. Существует AArch64/NEON порт Embree — Embree-aarch64, — недавно получивший обновления от команды Apple с целью добавления AVX2 в бэкэнд NEON. Embree в значительной степени оптимизирован для ширины SIMD, равной 8, поэтому, даже несмотря на то, что в данном случае нужно использовать 2 вектора NEON, чтобы он действовал как один вектор AVX2, так можно обеспечить лучшую производительность, чем бэкэнд шириной 4 на NEON.

ISPC — компилятор для программирования SIMD на ЦП, в котором пишутся скалярные программы, компилирующиеся для параллельной работы — по одному экземпляру программы на векторную дорожку. Каждая программа обрабатывает свои фрагменты данных параллельно с другими программами. Это что-то вроде GLSL или HLSL, работающих на ЦП, где скалярная программа выполняется параллельно с использованием SIMD. ОднакоISPC уже поддерживает NEON и AArch64, так что включение в него комбинации macOS+AArch64/NEON оказалось довольно простым. Для этого можно использовать такой PR.

Наконец, хотя TBB — библиотека Intel для многопоточности, она не имеет никакого отношения к конкретной архитектуре ЦП. Все, что нам нужно, — это собрать TBB для AArch64.

Бенчмарки

Теперь, когда ChameleonRT работает на ЦП и ГП чипа M1, можно провести несколько тестов. Для сравнения аналогичные тесты были проведены на i7-1165G7 в XPS 13 (тут стоит заметить, что у него могут возникнуть проблемы с нагреванием), на i7-4790K и на i9-9920X на Ubuntu. Что касается ГП, для сравнения был взят RTX 2070. Непосредственно M1 использовался с 16 ГБ оперативной памяти Mac Mini.

Для начала приведем цифры CineBench, о которых говорилось ранее:

CPU

Рейтинг CineBench R23

Относительно M1

i7-1165G7

4026

0,52x (M1 в ~1,93 раза быстрее)

i7-4790K

4579

0,59x (M1 в ~1,70 раза быстрее)

Apple M1

7783

i9-9920X

14793*

1,9x (M1 в ~1,9 раза медленнее)

Таблица 1. Результаты CineBench R23 на протестированных системах. Примечание: i9-9920X работает на Ubuntu, для которой CineBench недоступен.

Для тестов в ChameleonRT были использованы две сцены, показанные ниже: Sponza и San Miguel. Sponza — небольшая сцена с 262 тысячами треугольников, San Miguel — хороший челлендж для интерактивной трассировки лучей с 9,96 миллионами треугольников. Обе рассматриваются BVH билдером как суп из треугольников — то есть, создается единая структура ускорения нижнего уровня, содержащая все треугольники в сцене. Это дает BVH билдеру максимально возможную информацию о распределении геометрии, чтобы он мог построить высококачественную структуру ускорения. Обе сцены скачаны с этого сайта и повторно экспортированы в Blender, чтобы заменить группы материалов на формат OBJ, поскольку ChameleonRT поддерживает далеко не все форматы материалов. В тестах происходит рендеринг изображения разрешением 1280x720px для ~ 200 кадров, после чего снимаются значения средней частоты кадров (FPS) и миллиона лучей за секунду (MRay/s).

Рисунок 1. Сцены, использованные в тестах. Сцена Sponza содержит 262 тысяч треугольников.
Рисунок 1. Сцены, использованные в тестах. Сцена Sponza содержит 262 тысяч треугольников.
Рисунок 2. Сцены, использованные в тестах. Сцена San Miguel содержит 9,96 млн треугольников.
Рисунок 2. Сцены, использованные в тестах. Сцена San Miguel содержит 9,96 млн треугольников.

Справедливые сравнения

Под справедливым мы понимаем сравнение с другим мобильным процессором, в данном случае — i7-1165G7 на XPS 13, использующем Embree. Результаты сравнения здесь оказались немного больше в пользу M1, поскольку XPS 13 сильнее нагревается. Также приведены результаты для i7-4790K. Поначалу при запуске конфигурации для Embree в ChameleonRT XPS 13 может даже превзойти i7-4790K, но впоследствии он замедляется из-за нагрева.

i7-1165G7 имеет расширение AVX512, что позволяет ISPC запускать 16 потоков параллельно. В свою очередь, i7-4790K поддерживает AVX2, позволяя ISPC запускать 8 потоков параллельно. На M1 можно использовать ISPC для компиляции NEON с двойной подкачкой, то есть выполнения SIMD шириной 8 в 4-х разрядных регистрах NEON. Embree на M1 настроен для использования AVX2 на NEON, так как Embree оптимизирован для ширины SIMD, равной 8.

CPU

FPS

MRay/s

i7-1165G7 (AVX512)

1,56

8,7

i7-4790K (AVX2)

1,83

10,2

Apple M1

1,72

9,6

Таблица 2. Результаты тестов рендеринга Sponza с использованием Embree.

CPU

FPS

MRay/s

i7-1165G7 (AVX512)

1,07

6,1

i7-4790K (AVX2)

1,33

7,6

Apple M1

1,30

7,4

Таблица 3. Результаты тестов рендеринга San Miguel с использованием Embree.

Крайне несправедливые сравнения

Это сравнения трассировки лучей Metal на M1 с трассировкой лучей DirectX на RTX 2070 и Embree на i9-9920X. Понятно, что при таких сравнениях M1 будет не слишком конкурентоспособным, но все равно любопытно было проверить. RTX 2070 имеет TDP, равное 175 Вт, и аппаратное ускорение трассировки лучей, в то время как весь чип M1 оценивается примерно в 20-24 Вт и не имеет ускорения трассировки. i9-9920X имеет TDP, равное 165 Вт, и поддерживает AVX512 (с шириной SIMD 16) и AVX2 (ширина SIMD 8). Как видно из предыдущих тестов, поддержка более широкой SIMD (AVX2) на i7-4790K по-прежнему обеспечивает серьезную конкуренцию M1. Также в этих тестах выяснилось, что i9-9920X работает лучше всего при использовании AVX2. В тестах Трэвиса Даунса было замечено, что использование AVX512 на некоторых процессорах может привести к понижению тактовой частоты. В зависимости от того, насколько оптимизирована рабочая нагрузка для SIMD, на самом деле она может работать лучше при более высоких тактовых частотах и более узкой ширине SIMD, как в данном случае. Обратите внимание, что на i7-1165G7 AVX512 работает немного лучше, чем AVX2.

CPU

FPS

MRay/s

i9-9920X (AVX2)

6,02

33,6

Apple M1

1,72

9,6

Таблица 4. Крайне несправедливые тесты Sponza с использованием Embree.

CPU

FPS

MRay/s

i9-9920X (AVX2)

4,46

25,3

Apple M1

1,30

7,4

Таблица 5. Крайне несправедливые тесты San Miguel с использованием Embree.

GPU

FPS

MRay/s

RTX 2070 (DirectX Ray Tracing)

135,5

757

Apple M1 (Metal)

3,60

20,1

Таблица 6. Крайне несправедливые тесты Sponza на ГП.

GPU

FPS

MRay/s

RTX 2070 (DirectX Ray Tracing)

63,8

362

Apple M1 (Metal)

2,06

11,7

Таблица 7. Крайне несправедливые тесты San Miguel на ГП.

Подводя итог

Итак, M1 на CineBench показал производительность в 1,93 раза большую, чем i7-1165G7, но при тестах на ChameleonRT в обеих сценах в среднем он был всего в 1,16 раза быстрее. Точно так же M1 показал себя на CineBench в 1,70 раза более производительным, чем i7-4790K, но на самом деле оказался 1,05 раза медленнее в среднем по двум сценам. Что из этого следует?

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

В целом M1 очень неплох — как в плане производительности, так и бесшумности. О его практически полностью бесшумной работе действительно есть что сказать: его не было слышно ни в описанных выше тестах, ни при параллельной сборке LLVM для сборки ISPC.

Что действительно хотелось бы увидеть в будущих чипах M*, так это поддержку SIMD с шириной 8 и трассировки лучей с аппаратным ускорением. При запуске Embree на оборудовании с поддержкой SSE4 (SIMD шириной 4) обнаружилось, что он примерно в 1,6-1,8 раза медленнее, чем при работе с AVX2 (SIMD шириной 8). Даже если предположить, что мы получаем скорость всего в 1,6 раза больше на M1 с SIMD шириной 8, это приведет к тому, что с Embree частота кадров окажется ~ 2,75 FPS на Sponza и ~ 2,06 FPS на San Miguel.

Поддержка трассировки лучей с аппаратным ускорением на графическом процессоре также не была бы лишней. Но даже текущий уровень производительности впечатляет для столь легкого чипа, учитывая, что у него нет таких тепловых проблем, как, скажем, у XPS 13, и он может обеспечить несколько лучшую производительность на процессоре с шириной 1/4 SIMD (4 против 16), а также имеет API графического процессора, который обеспечивает в этих тестах ускорение в 1,6-2 раза по сравнению с ЦП.

Интересно посмотреть, какое оборудование Apple планирует для high-end сегмента.

 

Источник

apple, Apple M1, трассировка лучей

Читайте также