Skip to main content

Существует множество способов оптимизировать графический код Metal для достижения максимальной производительности. Вот как можно начать приводить свой код в лучшую форму для платформы Metal.

Архитектура графического процессора Apple

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

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

В большинстве современных программ Apple GPU геометрия рассчитывается и разбивается на сетки и полигоны, а затем преобразуется в пиксельное изображение, по одному изображению на кадр.

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

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

Современный конвейер рендеринга на графическом процессоре Apple.

Счетчики графических процессоров

Для измерения этой производительности используются счетчики графического процессора.

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

Наконец, счетчики графического процессора оптимизируют команды, которые занимают больше всего времени, чтобы повысить производительность.

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

Существует проблема понимания всех данных счетчика производительности. Для этого вы используете Metal System Trace и Metal Debugger, встроенные в Xcode и Instruments.

Существует четыре счетчика Metal GPU, которые включают важные способы оптимизации Metal в ваших приложениях и играх. Они есть:

Ограничители производительности. Занятость полосы пропускания памяти. Удаление скрытых поверхностей.

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

Современные графические процессоры выполняют математические операции, работу с памятью и растеризацию параллельно (одновременно). Ограничители производительности помогают выявить узкие места производительности, которые замедляют работу вашего кода.

Вы можете использовать приложение Apple Instruments, чтобы использовать ограничители производительности для оптимизации вашего кода. В Instruments имеется полдюжины различных ограничителей производительности.

Приложение Apple Instruments.

Приложение Apple Instruments.

Счетчики пропускной способности памяти

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

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

Если вы видите счетчик пропускной способности памяти с высоким значением, это, вероятно, означает, что передача замедляет рендеринг. Чтобы устранить эти узкие места, вы можете сделать несколько вещей.

Один из способов уменьшить замедление пропускной способности памяти — уменьшить размер рабочих наборов данных. Это ускоряет процесс, поскольку из системной памяти передается меньше данных.

Другой способ — загружать только данные, необходимые для текущего прохода рендеринга, и сохранять только данные, необходимые для будущих проходов рендеринга. Это также уменьшает общий размер данных.

Вы также можете использовать блочное сжатие текстур (ASTC) для уменьшения размеров текстурных ресурсов и сжатие без потерь для текстур, генерируемых во время выполнения.

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

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

Удаление скрытых поверхностей обычно происходит где-то в середине каждого прохода рендеринга перед обработкой фрагмента — вскоре после того, как мозаичный буфер вершин отправляется в графический процессор для растеризации.

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

Например, поверхности на обратной стороне непрозрачных 3D-объектов не нужно рисовать, поскольку камера (и зритель) их никогда не видит, поэтому нет смысла их рисовать.

Поверхности, скрытые другими 3D-объектами, находящимися перед ними относительно камеры, также удаляются.

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

Счетчики графического процессора также можно использовать для минимизации смешивания, что также приводит к снижению производительности.

Чтобы оптимизировать рисование с удалением скрытых поверхностей, вам нужно рисовать объекты в порядке состояния видимости, а именно проверять, являются ли объекты непрозрачными, проверять по полупрозрачности и стараться избегать чередования непрозрачных и непрозрачных сеток.

Ресурсы

Чтобы начать работу с оптимизацией Metal, обязательно посмотрите видеоролики WWDC «Оптимизация приложений и игр Metal с помощью счетчиков графических процессоров» из WWDC20, «Использование графических процессоров с Metal» также из WWDC20 и «Доставка оптимизированных приложений и игр для Metal» из WWDC19.

Затем прочитайте «Захват рабочей нагрузки Metal в Xcode» и «Типы отладки Metal» на страницах Metal Debugger на веб-сайте документации для разработчиков Apple.

В документации Metal Debugger также есть раздел «Анализ рабочей нагрузки Metal».

Вам определенно захочется потратить много времени на документацию Xcode Metal Debugger и Trace, чтобы подробно изучить, как работают различные счетчики графического процессора и графики производительности. Без них вы не сможете получить детальное представление о том, что на самом деле происходит в вашем Metal-коде.

Что касается сжатых текстур, также стоит прочитать об адаптивном масштабируемом сжатии текстур (ASTC) и о том, как оно работает в современных конвейерах рендеринга.

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