— Pixels Commander

[ In English, На русском ]

Скорость вычислений WebGPU в сравнении с WebGL

WebGPU — сменщик WebGL, новый API для работы с графическим ускорителем в браузере и появится в публичном Chrome в начале 2022 года. По сравнению с WebGL он обещает лучшее быстродействие и лучшую совместимость с последними моделями видеокарт, но самой большим нововведением WebGPU является специальный функционал для вычислений на GPU.Matrices multiplication WebGPU vs WebGL

Но разве WebGL не имел такой возможности?

И да и нет. Вычисления на WebGL сделаны через хак. Данные превращаются в изображение, которое загружается в WebGL как текстура, затем в пиксельном шейдере производятся вычисления и результат отображается в виде набора пикселов на канвасе. Считывание результатов производится с помощью getPixelsData. Выглядит не очень эффективно, да?

WebGL computation pipeline

В чем отличие WebGPU?

API который представляет WebGPU для вычислений (compute shaders) имеет несколько отличий которые на первый взгляд мало значительны, но при детальном рассмотрении дают разработчику новые возможности.

WebGPU computations pipeline

Отличия

  1. Данные не нужно преобразовывать в текстуру
  2. Вычисление выполняется асинхронно и не блокирует главный поток JS (привет сложная симуляция физики на 60FPS)
  3. Нам больше не нужен элемент canvas и связанные с его размером ограничения, вычисления производятся в памяти
  4. Нам не нужно выполнять дорогой и синхронный getPixelsData
  5. Нам не нужно конвертировать полученные значения пикселей в данные

Итого WebGPU обещает нам что вычисления можно будет делать не блокируя main thread и ощутимо быстрее, но насколько именно?

Как будем тестировать?

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

Для примера умножение матриц 16х16 требует 7936 операций умножения, а 60х60 уже 428400.

Я адаптировал существующий WebGL код для умножения матриц и код для вычислений на WebGPU. Запускать не текущий момент можно только в Chrome Canary с включенным флагом #unsafe-webgpu-enabled

Результаты

Первый результат был неожиданным:

Matrices multiplication benchmark WebGPU incorrect

После определенного размера матрицы WebGL начал обходить WebGPU. Оказалось что размер working group (количество одновременно выполняемых вычислений) был выставлен в коде так, что всегда был равен размеру матрицы. То есть при матрице 1024х1024 в шейдер отправлялся блок соответствующего размера и тк количество арифметических блоков на моем GPU равен 256 то вычисления выполнялись не оптимально, в несколько этапов. Количество ALU можно получить в коде как свойство WebGPU контекста maximumWorkingGroupSize. Как только я ограничил размер working group до 256 получил:Matrices multiplication WebGPU vs WebGL

Ожидаемо, из-за отсутствия необходимости в создании текстур и чтения данных с canvas накладные расходы на инициализацию у WebGPU значительно ниже, а быстродействие выше и с ростом объема вычислений эта разница только растет. Стоит отметить, что и WebGL и WebGPU требуют времени на разогрев.

Вывод

Мы экспериментально подтвердили, что по сравнению с WebGL вычисления на WebGPU имеет меньшую стоимость инициализации и выполняются в среднем в три раза быстрее кроме того из-за асинхронного API позволяют разгрузить главный поток браузера. Это позволяет выполнять в браузере новые типы задач: редактирование видео и аудио, симуляция физических процессов и более реалистичных визуальных эффектов — вот неполный список того, где с приходом WebGPU стоит ожидать новых, невозможных ранее решений.