Primary tabs

Bifrost встречается с GNOME: Вперед и вверх до нуля

Ссылка на оригинал - https://www.collabora.com/news-and-blog/blog/2020/06/05/bifrost-meets-gnome-onwa…, автор публикации - Alyssa Rosenzweig

В нашем последнем обновлении для Panfrost, бесплатного графического драйвера с открытым исходным кодом для современных графических процессоров Mali, мы объявили о начальной поддержке архитектуры Bifrost. С тех пор мы расширили эту поддержку на основные возможности OpenGL ES 2.0 и даже на некоторые функции настольной версии OpenGL 2.1. При использовании только свободного ПО, чип Mali G31 теперь может работать с композиторами Wayland, используя графику нулевого копирования, включая GNOME 3. Мы можем запускать каждую сцену в glmark2-es2, также можно играть в 3D игры вроде Neverball. Кроме того, поддерживается аппаратное ускорение для видеоплееров mpv и Kodi. Скриншоты выше – из платы Mali G31 под управлением Panfrost.

Все вышеперечисленное включено в состав восходящего потока Mesa без необходимости установки патчей вне дерева, с предстоящей поддержкой Bifrost через переменную окружения PAN_MESA_DEBUG=bifrost.

Collabora - GNOME Shell
Оболочка GNOME 
Collabora - Neverball
Neverball

Новые опкоды

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

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

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

Помимо новых опкодов ALU, расширена поддержка текстур, чтобы можно было включить простые операции с текстурами из вершинных шейдеров - паттерна, встречающегося в сцене с рельефом glmark2. В Mali GPU используются немного отличающиеся кодировки для операций с текстурами фрагментов и вершин, так как фрагментные шейдеры могут автоматически вычислять параметр уровня детализации на основе соседних фрагментов, в то время как в вершинных шейдерах нет соседних фрагментов.

Наконец, добавлена поддержка начального потока управления для операторов if/else и циклов. Поскольку Bifrost - это архитектура Single Instruction, Multiple Thread (SIMT), в которой несколько потоков работают одним и тем же шейдером в lockstep, ветвление является сложным делом, если потоки расходятся. Большая часть обрабатывается аппаратным обеспечением, но реализация ветвления заканчивается волосом, более сложным, чем в Мидгарде. Тем не менее, этого достаточно для петли glmark2, и всегда есть место для улучшений.

Упрощение IR

Кстати, прогресс в области бифроста не является препятствием для улучшения поддержки в Мидгарде. Вдохновившись уроками, извлеченными из опыта проектирования Bifrost Intermediate Representation в том виде, в каком они были ранее опубликованы в блоге, также мы пересмотрели Midgard Intermediate Representation. Внимание было сосредоточено на двух аспектах:

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

Для этого были внедрены общие хелперы для вывода модификаторов инструкций, таких как насыщенность. Рассмотрим шейдер, который помещает переменную в квадрат и насыщает ее в диапазон [0, 1].

X = clamp(X * X, 0.0, 1.0);

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

ssa_10 = fmul ssa_9, ssa_9

ssa_11 = fsat ssa_10

Наше аппаратное обеспечение имеет встроенную поддержку насыщения результатов инструкций с плавающей точкой. Есть несколько подходов для использования. Один из них - использовать обработку насыщения builtin из NIR, как это делал компилятор Midgard. Пропуск NIR может соединить инструкцию fsat с умножением, создавая NIR:

ssa_10 = fmul.sat ssa_9, ssa_9

В таком случае наш компилятор бэкэнда может напрямую использовать флаг .sat. Несмотря на то, что это простой подход, он негибкий, так как аппаратное обеспечение может использовать модификаторы, которые NIR не выражает. Например, у графических процессоров Mali GPU есть операция .clamp_positive, которая свободно делает результат max(x, 0.0). Если бы мы написали X = max(X * X, 0.0), NIR могла бы дать нам код, используя специальную инструкцию fclamp_positive:

ssa_10 = fmul ssa_9, ssa_9

ssa_11 = fclamp_positive ssa_10

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

10 = fmul 9, 9                        10 = fmul.pos 9, 9

11 = fclamp_positive ssa_10

Однако есть третий вариант, объединяющий оба варианта и упрощающий компилятор: выводить модификаторы генерически, при трансляции NIR в наш бэкенд IR. Это позволяет использовать модификаторы, специфичные для архитектуры, такие как .pos, при этом сохраняя оригинальную NIR для эффективной работы. Такой подход позволил нам заменить сотни строк оптимизаций для модификаторов с плавающей точкой и битовых инверторов, одновременно оптимизируя новые шаблоны, которые оригинальная конструкция не смогла создать, обещая экономию в сложности кода и улучшении производительности. Поскольку он является универсальным, он позволяет нам оптимизировать не только программы Midgard, но и, в скором времени, модификаторы Bifrost.

Midgard FP16

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

Чтобы подготовиться, мы добавили типы в IR, чтобы избежать проходов компилятора, требующих вывода типа, сложного и склонного к ошибкам. После того, как размер типов был сохранен в чистом виде, мы добавили дополнительную поддержку процедур упаковки компилятора Midgard, чтобы обрабатывать некоторые выдающиеся детали 16-битных инструкций. Midgard значительно проще упаковывать, чем Bifrost; в то время как 16-битные и 32-битные инструкции в Bifrost включают в себя отдельные инструкции с сильно отличающимися опкодами и форматами, Midgard использует подход, основанный на одном размере, который, несмотря на присущие ему ограничения, является более оптимальным вариантом. В компиляторе требовались различные исправления; тем не менее, упрощенный IR выполнил свою задачу и теперь способен поддерживать 16-битные операции.

Большая часть кода, необходимого для FP16, теперь находится в верхней части Mesa, но по умолчанию отключена в ожидании дальнейшего тестирования. Тем не менее, для любителей приключений можно установить PAN_MESA_DEBUG=fp16 на недавней сборке мастера. 

Цветные маски

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

glColorMask(true, true, true, true);

glDepthMask(true);

glDrawArrays(GL_TRIANGLES, 0, 15);

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

glColorMask(false, false, false, false);

glDepthMask(true);

glDrawArrays(GL_TRIANGLES, 0, 15);

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

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

Даже если требуются обновления глубины/трафарета, до тех пор, пока шейдер вычисляет только цвет без побочных эффектов, нет причин запускать шейдер. Хотя Bifrost не появляется, Midgard позволяет драйверу указать отрисовку без шейдера, сохраняя не только чтение/запись цветового буфера, но и выполнение шейдера.

Вклад сообщества

В дополнение к нашей работе над производительностью Midgard, хакер Icecream95 занимается улучшением стека Midgard.

С момента нашего последнего поста в блоге, они внесли большое исправление для работы с инструкциями по отбраковке. Для фона, OpenGL сначала запускает шейдер фрагментов для каждого пикселя на экране, а затем выполняет тестирование глубины. На практике, современные аппаратные средства пытаются выполнять тесты глубины перед запуском шейдера, известные как тестирование"early-z", чтобы избежать ненужного выполнения шейдера для окклюдированных пикселей.

Тем не менее, игры используют отбрасывание, директиву OpenGL, позволяющую шейдерам удалять фрагменты, которые могут помешать оптимизациям типа "early-z". Драйвер отвечает за обнаружение таких ситуаций, отключение этих оптимизаций и включение соответствующих стандартам путей отката, включая тестирование "late-z". После того, как Icecream95 исследовал проблемы работы Panfrost с глубинным тестированием при наличии инструкций по отбрасыванию, они смогли исправить ошибки рендеринга во многих играх, включая SuperTuxKart, OpenMW и RVGL.

Что касается производительности, то была значительно оптимизирована процедура Panfrost и расчет индекса Mesa min/max, а также добавлена поддержка сжатых текстур ASTC и ETC.

Некоторые скриншоты игр Panfrost (Mali T760), улучшенных патчами Icecream95:

Снимаем шляпу перед участником сообщества!

Счетчики производительности

Одна из последних областей, над которой мы работаем, это разоблачение счетчиков производительности Mali в пользовательском пространстве в Panfrost, что позволяет нам выявить узкие места в драйвере, а также определить узкие места в приложениях, работающих на Panfrost. Примерно год назад мы обладали экспериментальной поддержкой передачи счетчиков из пространства ядра. Антонио Кагджано и Рохан Гарг, совместно с Icecream95 и другими участниками, работали над интеграцией этих счетчиков с Perfetto, чтобы дать возможность анализа высокого уровня элегантному, свободному пользователю ПО

Perfetto с Panfrost на Mali T760

Заглядывая в будущее

За последние 3 месяца, с тех пор как мы начали работу над Bifrost, мы с коллегой Томеу Визосо (Tomeu Vizoso) продвинулись от того, чтобы в марте выпустить новый компилятор и командный поток, а к маю запустить настоящие программы. Движимые усилиями по обратному проектированию в тандеме с сообществом свободного программного обеспечения, мы уверены, что вопреки несвободным блокам и последующим взломам, программное обеспечение с открытым исходным кодом будет преобладать.

Заглядывая в будущее, мы планируем улучшить покрытие Bifrost OpenGL ES 2.0 для поддержки большего количества 3D-игр, теперь, когда базовый ускоренный десктоп функционирует. Мы также планируем улучшить производительность компилятора Bifrost, чтобы приблизиться к производительности проприетарного стека, как мы это делали для Midgard. Прежде всего, мы хотели бы создать сообщество, с программной свободой и открытым первым подходом в качестве основных ценностей.

Это работало для Freedreno, Etnaviv и Lima; для Panfrost на Midgard. И я уверен, что это снова сработает на Bifrost.

Счастливого взлома.

Добавить комментарий

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Не нашли ответ на свой вопрос? Возможно, вы найдете решение проблемы на нашем канале в Youtube! Здесь мы собрали небольшие, но эффективные инструкции. Смотрите и подписывайтесь на наш youtube-канал!

Смотреть на Youtube