WebGPU: разблокировка доступа к современному графическому процессору в браузере

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

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

Контекст на WebGPU

WebGL появился в Chrome в 2011 году . Позволяя веб-приложениям использовать преимущества графических процессоров, WebGL обеспечивает потрясающие возможности работы в Интернете — от Google Earth до интерактивных музыкальных видеороликов, 3D-обзоров недвижимости и многого другого. WebGL был основан на семействе API OpenGL, впервые разработанном в 1992 году. Это было очень давно! И вы можете себе представить, что с тех пор аппаратное обеспечение графических процессоров значительно изменилось.

Чтобы идти в ногу с этой эволюцией, было разработано новое поколение API-интерфейсов для более эффективного взаимодействия с современным оборудованием графического процессора. Такие API, как Direct3D 12 , Metal и Vulkan . Эти новые API-интерфейсы поддерживают новые и требовательные варианты использования программирования графических процессоров, такие как бурный рост машинного обучения и достижения в алгоритмах рендеринга. WebGPU является преемником WebGL, привнося в Интернет достижения этого нового класса современных API.

WebGPU открывает множество новых возможностей программирования графических процессоров в браузере. Он лучше отражает то, как работает современное оборудование графического процессора, а также закладывает основу для более продвинутых возможностей графического процессора в будущем. Этот API разрабатывается в группе W3C «GPU for the Web» с 2017 года и является результатом сотрудничества многих компаний, таких как Apple, Google, Mozilla, Microsoft и Intel. И теперь, после 6 лет работы, мы рады сообщить, что одно из крупнейших дополнений к веб-платформе наконец-то доступно!

WebGPU доступен сегодня в Chrome 113 на ChromeOS, macOS и Windows; скоро появятся и другие платформы. Огромное спасибо другим участникам Chromium и в частности Intel, которые помогли сделать это возможным.

Теперь давайте посмотрим на некоторые интересные варианты использования, которые предоставляет WebGPU.

Разблокируйте новые рабочие нагрузки графического процессора для рендеринга

Функции WebGPU, такие как вычислительные шейдеры, позволяют переносить новые классы алгоритмов на графический процессор. Например, алгоритмы, которые могут добавлять в сцены больше динамических деталей, моделировать физические явления и многое другое! Есть даже рабочие нагрузки, которые раньше можно было выполнить только с помощью JavaScript, а теперь можно перенести на графический процессор.

В следующем видео показан алгоритм марширующих кубов, используемый для триангуляции поверхности этих меташаров. В первые 20 секунд видео алгоритм, работающий на JavaScript, с трудом успевает за страницей, работающей только со скоростью 8 кадров в секунду, что приводит к дерганной анимации. Чтобы сохранить производительность в JavaScript, нам придется значительно снизить уровень детализации.

Это разница дня и ночи, когда мы переносим один и тот же алгоритм в вычислительный шейдер, что видно на видео через 20 секунд. Производительность значительно повышается: страница теперь плавно работает со скоростью 60 кадров в секунду, и остается еще большой запас производительности для других эффектов. Кроме того, основной цикл JavaScript страницы полностью освобождается для других задач, что гарантирует оперативность взаимодействия со страницей.

Демо-версия метаболлов

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

Демо-версия океана

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

Более быстрый вывод ML

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

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

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

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

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

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

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

В качестве примера повышения эффективности, которое это может принести, первоначальный порт модели распространения изображений в TensorFlow.js показывает трехкратный прирост производительности на различном оборудовании при переходе с WebGL на WebGPU. На некоторых протестированных аппаратных средствах изображение отображалось менее чем за 10 секунд. И поскольку это был ранний порт, мы считаем, что как в WebGPU, так и в TensorFlow.js возможно еще больше улучшений! Узнайте , что нового в Web ML в 2023 году? Сеанс ввода-вывода Google.

Но WebGPU — это не только предоставление возможностей графического процессора в Интернет.

Разработан в первую очередь для JavaScript

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

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

Мы увидели, что глобальная модель состояний WebGL делает создание надежных, компонуемых библиотек и приложений трудным и хрупким. Таким образом, WebGPU значительно сокращает объем состояния, который разработчикам необходимо отслеживать при отправке команд графического процессора.

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

Мы также увидели, что часто накладные расходы, связанные с выполнением слишком большого количества вызовов JavaScript, становятся узким местом для сложных приложений WebGL. В результате API WebGPU становится менее болтливым, поэтому вы можете добиться большего с меньшим количеством вызовов функций. Мы концентрируемся на выполнении тщательной проверки заранее, сохраняя критический цикл отрисовки как можно более компактным. И мы предлагаем новые API, такие как Render Bundles , которые позволяют заранее записывать большое количество команд рисования и воспроизводить их одним вызовом.

Чтобы продемонстрировать, насколько существенно может измениться такая функция, как пакеты рендеринга, вот еще одна демонстрация от Babylon.js. Их рендерер WebGL 2 может выполнять все вызовы JavaScript для рендеринга этой сцены художественной галереи примерно 500 раз в секунду. Что очень хорошо!

Художественная галерея

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

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

Это имеет приятный побочный эффект: WebGPU легко изучить и использовать. Он опирается на существующие функции веб-платформы для таких вещей, как загрузка изображений и видео, а также опирается на известные шаблоны JavaScript, такие как Promises, для асинхронных операций. Это помогает свести к минимуму количество необходимого шаблонного кода. Вы можете вывести свой первый треугольник на экран менее чем за 50 строк кода.

<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
  const adapter = await navigator.gpu.requestAdapter();
  const device = await adapter.requestDevice();

  const context = canvas.getContext("webgpu");
  const format = navigator.gpu.getPreferredCanvasFormat();
  context.configure({ device, format });

  const code = `
    @vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
      @builtin(position) vec4f {
       const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
       return vec4f(pos[i], 0, 1);
    }
    @fragment fn fragmentMain() -> @location(0) vec4f {
      return vec4f(1, 0, 0, 1);
    }`;
  const shaderModule = device.createShaderModule({ code });
  const pipeline = device.createRenderPipeline({
    layout: "auto",
    vertex: {
      module: shaderModule,
      entryPoint: "vertexMain",
    },
    fragment: {
      module: shaderModule,
      entryPoint: "fragmentMain",
      targets: [{ format }],
    },
  });
  const commandEncoder = device.createCommandEncoder();
  const colorAttachments = [
    {
      view: context.getCurrentTexture().createView(),
      loadOp: "clear",
      storeOp: "store",
    },
  ];
  const passEncoder = commandEncoder.beginRenderPass({ colorAttachments });
  passEncoder.setPipeline(pipeline);
  passEncoder.draw(3);
  passEncoder.end();
  device.queue.submit([commandEncoder.finish()]);
</script>

Заключение

Приятно видеть все новые возможности, которые WebGPU привносит в веб-платформу, и мы с нетерпением ждем возможности увидеть все новые интересные варианты использования, которые вы найдете для WebGPU!

Вокруг WebGL была построена динамичная экосистема библиотек и фреймворков, и эта же экосистема стремится охватить WebGPU. Поддержка WebGPU находится в разработке или уже завершена во многих популярных библиотеках Javascript WebGL, и в некоторых случаях воспользоваться преимуществами WebGPU может быть так же просто, как изменить один флаг!

Babylon.js, Construct 3, Google Earth, Google Meet, PlayCanvas, Sketchfab, Three.JS, TensorFlow.js и Unity.
Фреймворки, приложения и библиотеки с готовыми или текущими портами WebGPU.

И этот первый выпуск Chrome 113 — это только начало. Хотя наш первоначальный выпуск предназначен для Windows, ChromeOS и MacOS, в ближайшем будущем мы планируем перенести WebGPU на остальные платформы, такие как Android и Linux.

И не только команда Chrome работает над запуском WebGPU. Реализации также находятся в разработке в Firefox и WebKit.

Кроме того, в W3C уже разрабатываются новые функции, которые можно будет реализовать, когда они станут доступны на аппаратном уровне. Например: в Chrome мы планируем вскоре включить поддержку 16-битных чисел с плавающей запятой в шейдерах и инструкций класса DP4a, чтобы еще больше повысить производительность машинного обучения.

WebGPU — это обширный API, который открывает потрясающую производительность, если вы вложите в него средства. Сегодня мы смогли рассказать о его преимуществах только на высоком уровне, но если вы хотите начать работу с WebGPU, ознакомьтесь с нашей вводной Codelab, «Ваше первое приложение WebGPU» . В этой кодовой лаборатории вы создадите версию классической «Игры жизни» Конвея на графическом процессоре. Эта лаборатория шаг за шагом проведет вас через весь процесс, так что вы сможете опробовать его, даже если вы впервые занимаетесь разработкой графического процессора.

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