Dowiedz się, jak WebGPU wykorzystuje możliwości karty graficznej, aby przyspieszyć działanie systemów uczących się i poprawić renderowanie grafiki.
Nowy interfejs WebGPU API zapewnia ogromne wzrosty wydajności w przypadku obciążeń związanych z grafiką i uczeniem maszynowym. Z tego artykułu dowiesz się, dlaczego WebGPU jest lepszym rozwiązaniem niż obecne WebGL, a także co nowego pojawi się w przyszłości. Najpierw jednak wyjaśnimy, dlaczego powstało WebGPU.
Kontekst w WebGPU
WebGL pojawił się w Chrome w 2011 roku. Dzięki temu, że WebGL umożliwia aplikacjom internetowym korzystanie z kart graficznych, w internecie można uzyskać niesamowite wrażenia – od Google Earth po interaktywne teledyski i przejścia 3D po nieruchomościach. WebGL opiera się na rodzinie interfejsów API OpenGL, która została po raz pierwszy opracowana w 1992 r. To było dawno temu. Od tego czasu sprzęt GPU znacznie się rozwinął.
Aby nadążyć za tą ewolucją, opracowaliśmy nowe interfejsy API, które umożliwiają bardziej efektywną współpracę z nowoczesnym sprzętem GPU. Interfejsy API takie jak Direct3D 12, Metal i Vulkan. Te nowe interfejsy API obsługują nowe i wymagające przypadki użycia programowania na GPU, takie jak gwałtowny rozwój uczenia maszynowego i ulepszanie algorytmów renderowania. WebGPU to następca WebGL, który wprowadza do internetu innowacje tej nowej klasy nowoczesnych interfejsów API.
WebGPU otwiera wiele nowych możliwości programowania GPU w przeglądarce. Lepiej odzwierciedla ono działanie nowoczesnego sprzętu GPU, a zarazem tworzy podstawę dla bardziej zaawansowanych funkcji GPU w przyszłości. Interfejs API został opracowany w ramach grupy GPU for the Web firmy W3C od 2017 roku i jest wynikiem współpracy między wieloma firmami, takimi jak Apple, Google, Mozilla, Microsoft i Intel. Po 6 latach pracy możemy w końcu ogłosić, że jedna z największych nowości na platformie internetowej jest już dostępna.
WebGPU jest już dostępne w Chrome 113 na systemach ChromeOS, macOS i Windows, a wkrótce pojawi się na innych platformach. Dziękujemy wszystkim, którzy przyczynili się do rozwoju Chromium, a w szczególności firmie Intel.
Przyjrzyjmy się teraz kilku ekscytujących zastosowaniach WebGPU.
Odblokuj nowe obciążenia GPU do renderowania
Funkcje WebGPU, takie jak shadery obliczeniowe, umożliwiają przenoszenie nowych klas algorytmów na GPU. Na przykład algorytmy, które mogą dodawać więcej dynamicznych szczegółów do scen, symulować zjawiska fizyczne i tak dalej. Istnieją nawet zadania, które wcześniej można było wykonywać tylko przy użyciu JavaScriptu, a teraz można przenieść je do GPU.
Ten film pokazuje, jak algorytm marching cubes służy do triangulacji powierzchni tych metakul. W ciągu pierwszych 20 sekund filmu algorytm, który działa w języku JavaScript, trudzi się za to, aby strona działała z szybkością tylko 8 FPS, co powoduje zacinanie animacji. Aby zachować wydajność w JavaScript, musielibyśmy znacznie obniżyć poziom szczegółów.
Gdy przenosimy ten sam algorytm do cieniowania obliczeniowego, który jest widoczny na filmie po 20 sekundach, powstaje różnica w dniu i nocy. Wydajność znacznie się poprawia, ponieważ strona działa teraz z płynną szybkością 60 FPS, a nadal jest sporo miejsca na nowe efekty. Oprócz tego główna pętla JavaScript na stronie zostaje całkowicie uwolniona na inne zadania, dzięki czemu interakcje ze stroną pozostają elastyczne.
WebGPU umożliwia też tworzenie złożonych efektów wizualnych, które wcześniej nie były możliwe. W tym przykładzie, utworzonym w popularnej bibliotece Babylon.js, powierzchnia oceanu jest symulowana całkowicie na karcie graficznej. Realistyczna dynamika powstaje dzięki dodawaniu do siebie wielu niezależnych fal. Symulowanie każdej fali bezpośrednio byłoby jednak zbyt drogie.
Dlatego w demo używamy zaawansowanego algorytmu o nazwie szybka transformacja Fouriera. Zamiast przedstawiania wszystkich fal jako złożonych danych pozycyjnych, używa danych spektralnych, które są znacznie wydajniejsze do wykonywania obliczeń. Następnie w każdym ujęciu wykorzystuje się transformację Fouriera do przekształcenia danych widmowych na dane pozycyjne, które reprezentują wysokość fal.
Szybsze wnioskowanie ML
WebGPU jest też przydatne do przyspieszania uczenia maszynowego, które w ostatnich latach stało się głównym zastosowaniem procesorów GPU.
Od dawna twórcy treści korzystają z interfejsu API do renderowania WebGL do wykonywania operacji innych niż renderowanie, takich jak obliczenia systemów uczących się. Wymaga to jednak rysowania pikseli trójkątów w celu zainicjowania obliczeń oraz starannego pakowania i rozpakowywania danych tensora w teksturze zamiast ogólnego dostępu do pamięci.
Korzystanie z WebGL w ten sposób wymaga od programistów niezręcznego dostosowania swojego kodu do wymagań interfejsu API przeznaczonego tylko do rysowania. W połączeniu z brakiem podstawowych funkcji, takich jak dostęp do wspólnej pamięci między obliczeniami, prowadzi to do powielania pracy i nieoptymalnej wydajności.
Shadery obliczeniowe to główna nowa funkcja WebGPU, która rozwiązuje te problemy. Moduły do cieniowania Compute to bardziej elastyczny model programowania, który wykorzystuje bardzo równoległą naturę GPU i nie jest ograniczany przez ścisłą strukturę operacji renderowania.
Moduły do cieniowania Compute dają większe możliwości udostępniania danych i wyników obliczeń w grupach zadań do cieniowania, aby zwiększyć wydajność. Może to przynieść znaczne korzyści w porównaniu z wcześniejszymi próbami użycia WebGL do tego samego celu.
Jako przykład zwiększenia wydajności, jakie może to przynieść, początkowe przeniesienie modelu dyfuzji obrazu do TensorFlow.js pokazuje 3-krotny wzrost wydajności na różnych urządzeniach po przeniesieniu z WebGL do WebGPU. Na niektórych testowanych sprzętach obraz został wyrenderowany w czasie krótszym niż 10 sekund. Ponieważ był to wczesny port, uważamy, że można jeszcze bardziej ulepszyć zarówno WebGPU, jak i TensorFlow.js. Przeczytaj artykuł Co nowego w narzędziach do uczenia maszynowego w internecie w 2023 r.? Sesja na konferencji Google I/O.
WebGPU to jednak nie tylko udostępnianie funkcji GPU w internecie.
Zaprojektowane z myślą o JavaScript
Funkcje umożliwiające te zastosowania są od jakiegoś czasu dostępne dla deweloperów platform na komputery i urządzenia mobilne. Naszym wyzwaniem było udostępnienie ich w sposób, który sprawia wrażenie naturalnego elementu platformy internetowej.
Opracowano go, korzystając z danych uzyskanych od ponad 10 lat programistów pracujących nad WebGL. Udało nam się zebrać informacje o problemach, z którymi się spotkali, o wąskich gardłach, na które natrafili, i o problemach, które zgłosili, i przekazać je w ramach tego nowego interfejsu API.
Zauważyliśmy, że model globalnego stanu WebGL utrudnia i utrudnia tworzenie niezawodnych, składanych bibliotek i aplikacji. WebGPU znacznie zmniejsza ilość stanu, który deweloperzy muszą śledzić podczas wysyłania poleceń GPU.
Zdajemy sobie sprawę, że debugowanie aplikacji WebGL jest uciążliwe, dlatego WebGPU zawiera bardziej elastyczne mechanizmy obsługi błędów, które nie pogarszają wydajności. Dołożyliśmy wszelkich starań, aby każda wiadomość z interfejsu API była zrozumiała i użyteczna.
Zauważyliśmy też, że w przypadku złożonych aplikacji WebGL często wąskim gardłem jest nadmiar wywołań JavaScriptu. W rezultacie interfejs WebGPU API jest mniej „gadatliwy”, więc możesz osiągnąć więcej przy mniejszym wykorzystaniu wywołań funkcji. Skupiamy się na przeprowadzaniu kompleksowej weryfikacji z góry, aby pętla rysowania była jak najbardziej zwięzła. Oferujemy też nowe interfejsy API, takie jak Render Bundles, które umożliwiają wcześniejsze rejestrowanie dużej liczby poleceń rysowania i odtwarzanie ich za pomocą jednego wywołania.
Aby zademonstrować istotną różnicę w działaniu funkcji takich jak pakiety renderowania, oto kolejna wersja demonstracyjna pliku Babylon.js. Jej mechanizm renderowania WebGL 2 może wykonywać wszystkie wywołania JavaScriptu, by wyrenderować scenę z galerii sztuki mniej więcej 500 razy na sekundę. To całkiem nieźle.
Ich procesor graficzny WebGPU umożliwia jednak funkcję, którą nazywają renderowaniem migawki. Ta funkcja oparta na pakietach renderowania WebGPU umożliwia ponad 10-krotne przesyłanie tej samej sceny ponad 10 razy szybciej. Dzięki temu znacznie zmniejszony nakład pozwala WebGPU na renderowanie bardziej złożonych scen, a także umożliwia aplikacjom równoległe wykonywanie większej liczby zadań w języku JavaScript.
Nowoczesne interfejsy API grafiki mają opinię skomplikowanych, ponieważ rezygnują z prostoty na rzecz możliwości ekstremalnej optymalizacji. WebGPU skupia się natomiast na kompatybilności między platformami i w większości przypadków automatycznie obsługuje tradycyjnie trudne tematy, takie jak synchronizacja zasobów.
Ma to przyjemny efekt uboczny, ponieważ WebGPU jest łatwy do nauczenia i użycia. Korzysta z dotychczasowych funkcji platformy internetowej do wykonywania takich operacji jak wczytywanie obrazów i filmów oraz wykorzystuje znane wzorce JavaScriptu, takie jak obietnice (ang. promise) do wykonywania operacji asynchronicznych. Dzięki temu ograniczysz do minimum ilość stałego kodu. Pierwszy trójkąt na ekranie możesz uzyskać za pomocą mniej niż 50 wierszy kodu.
<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>
Podsumowanie
Cieszymy się, że WebGPU otwiera przed nami nowe możliwości na platformie internetowej. Nie możemy się doczekać, aż zobaczymy wszystkie nowe zastosowania WebGPU.
Wokół WebGL powstał bogaty ekosystem bibliotek i ramek, który chętnie przyjmie WebGPU. Obsługa WebGPU jest w trakcie implementacji lub już zakończona w wielu popularnych bibliotekach Javascript WebGL, a w niektórych przypadkach korzystanie z zalet WebGPU może być tak proste jak zmiana pojedynczej flagi.
Ta pierwsza wersja w Chrome 113 to dopiero początek. Chociaż nasza pierwsza wersja jest przeznaczona dla systemów Windows, ChromeOS i macOS, wkrótce planujemy udostępnić WebGPU na pozostałych platformach, takich jak Android i Linux.
Nie tylko zespół Chrome pracował nad wprowadzeniem WebGPU. Wdrożenia są też w trakcie w Firefox i WebKit.
Co więcej, nowe funkcje są już projektowane w W3C i będzie można je udostępnić, jeśli będą dostępne na sprzęcie. Na przykład w Chrome planujemy wkrótce udostępnić obsługę 16-bitowych liczb zmiennoprzecinkowych w shaderach oraz klasę instrukcji DP4a, aby jeszcze bardziej zwiększyć wydajność uczenia maszynowego.
WebGPU to rozbudowany interfejs API, który zapewnia niesamowitą wydajność, jeśli zainwestujesz w niego. Dzisiaj omówiliśmy tylko ogólnie zalety tej technologii, ale jeśli chcesz zacząć korzystać z WebGPU, zapoznaj się z wprowadzającym Codelab Twoja pierwsza aplikacja WebGPU. W tym Codelab utworzysz wersję klasycznej gry Conwaya „Game of Life” wykorzystującą GPU. To ćwiczenie programistyczne zawiera omówienie procesu krok po kroku, dzięki czemu możesz je wypróbować, nawet jeśli po raz pierwszy zajmujesz się programowaniem na procesor GPU.
Aby zapoznać się z interfejsem API, możesz też skorzystać z próbek WebGPU. Są to tradycyjne „trójkąty powitalne” i bardziej kompleksowe ścieżki renderowania i przetwarzania, które demonstrują różne techniki. Na koniec zapoznaj się z naszymi innymi materiałami.