Arkusze Google to jedna z pierwszych usług Google, które korzystają z WasmGC w Chrome. Ogłoszono to w 2022 r., a zespoły Arkuszy i Chrome wspólnie pracują nad standaryzacją, inżynierią i narzędziami, aby w czasie rzeczywistym przekazywać opinie na temat optymalizacji. Ta współpraca zapoczątkowała nowy sposób, w jaki zespoły inżynierów Google mogą skutecznie współpracować z Chrome, aby w WasmGC działało więcej aplikacji Google.
Wyzwanie: JavaScript
Mechanizm obliczania Arkuszy Google został pierwotnie napisany w Javie i został uruchomiony w 2006 roku. Początkowo wszystkie obliczenia odbywały się na serwerze. Jednak od 2013 roku mechanizm ten działa w przeglądarce z wykorzystaniem JavaScriptu. Początkowo używano do tego pakietu narzędzi Google Web Toolkit (GWT), a później używano transpilatora języka Java to Closure JavaScript (J2CL). Mechanizm obliczania JavaScriptu działa w narzędziu Web Worker i komunikuje się z wątkiem głównym za pomocą interfejsu MessageChannel
.
Migracja użytkowników z serwera do wersji JavaScriptu (a później z GWT do J2CL) była ważnym przedsięwzięciem, które wymagało dokładnej weryfikacji. Aby mieć pewność, że mechanizm obliczania JavaScript generował dokładnie te same wyniki co wersja w Javie, zespół Arkuszy opracował wewnętrzny mechanizm weryfikacji. Ten mechanizm może przetworzyć duży zbiór arkuszy i sprawdzić, czy wyniki różnych wersji silnika obliczeniowego są identyczne. Zespół Arkuszy regularnie używa tego narzędzia do sprawdzania zmian w Arkuszach. Jednak zespół nie tylko porównał wyniki tych obliczeń, ale także porównał wydajność języka JavaScript w kliencie i Javy na serwerze. Okazało się, że wersja JavaScriptu silnika obliczeniowego była ponad 3 razy wolniejsza niż wersja Java.
Dlaczego JavaScript jest wolniejszy niż Java?
JavaScript jest szybki w przypadku luźno wpisanego języka dynamicznego. Duże inwestycje w kompilatory „just-in-time” (JIT) (takie jak Maglev, Sparkplug i Turbofan) w ciągu ostatnich 15 lat zwiększyły wydajność JavaScriptu. Luźne typy i dynamiczne zachowanie JavaScriptu utrudniają jednak kompilatorom JIT wygenerowanie optymalnego kodu. Oznacza to, że JavaScript wciąż jest o tyle w stosunku do takich języków jak Java i C++, jeśli chodzi o przepustowość. TypeScript zwiększa bezpieczeństwo typów w skrypcie JavaScript, ale informacje o typie są zaprojektowane w taki sposób, aby ułatwić programowanie, a nie zapewnić gwarancje wymagane przez kompilatory do wygenerowania optymalnego kodu. W przypadkach takich jak Arkusze Google, w których obliczenie dużych arkuszy kalkulacyjnych może trwać dziesiątki sekund, JavaScript jest szybki, ale nie dostatecznie szybko.
Rozwiązanie: WasmGC
WasmGC to rozszerzenie istniejącej specyfikacji WebAssembly, która dodaje elementy podstawowe potrzebne do kompilowania języków do czyszczenia pamięci masowej (takich jak Java). Na przykład WasmGC dodaje instrukcje definiowania typów i przydzielania struktur danych zbieranych do kosza. WasmGC ma pomóc w usuwaniu odpadów w językach, tak jak było to możliwe w przypadku języka C++ (np. Photoshop i Google Earth), aby udostępniać je w internecie z szybkością zbliżonym do natywnego. W Google wierzymy, że ze względu na popularność języka używanego do zbierania odpadów, WasmGC może mieć jeszcze większe znaczenie niż Wasm.
Google Workspace współpracuje z Chrome
Wersja robocza specyfikacji WasmGC MVP została opublikowana w 2019 roku. Pod koniec 2020 roku zespoły Google Workspace i Chrome nawiązały współpracę, aby ocenić WasmGC za pomocą mechanizmu obliczania Arkuszy. Wieloplatformowy zespół Workspace ma duże doświadczenie w tworzeniu i optymalizowaniu kompilatorów i transpilatorów. Arkusze, które są częścią Workspace, zostały uznane za idealny kandydat do oceny WasmGC: cechują się dużą wydajnością i zaawansowanymi mechanizmami weryfikacji wydajności i poprawności. Zespół Chrome ma zespół V8, który tworzy i optymalizuje środowisko wykonawcze WasmGC, a także pomaga w Binaryen opracowywać optymalizacje z wyprzedzeniem (AOT). Zarówno Chrome, jak i Workspace mają do dyspozycji całą wiedzę specjalistyczną niezbędną do stworzenia i zoptymalizowania łańcucha narzędzi WasmGC, a Arkusze Google idealnie nadają się do testowania.
Pierwszy prototyp
W połowie 2021 roku zespoły miały już działający kompilator Java do WasmGC. Pod koniec tego samego roku opracowano prototypową wersję Arkuszy Google, która działała jako WasmGC i wykonywała obliczenia. Po drodze mierzyli się z wieloma wyzwaniami. Narzędzia do profilowania i robienia zrzutów stosu nie istniały i trzeba było je opracować. Dotychczasowa implementacja opierała się na wielu bibliotekach JavaScript, w przypadku których trzeba było znaleźć lub napisać zamienniki WasmGC. Weryfikacja poprawności silnika obliczeń Wasm była czasochłonna ze względu na eksperymentalny charakter specyfikacji, kompilatora i nowych bibliotek. Jednak mechanizmy weryfikacji Arkuszy znów były niezwykle pomocne. Ostatecznie zespoły zaczęły wszystko działać, a dane o skuteczności pojawiły się na początku 2022 roku.
Dodatkowe optymalizacje
Początkowa wersja Arkuszy Wasm wykazała wydajność obliczeniową około 2 razy wolniej niż JavaScript. Nie jest to jednak zły wynik w przypadku nowej specyfikacji, nowego kompilatora i kilku nowych bibliotek. Od tego momentu zespół Arkuszy rozpoczął optymalizację. Z optymalizacji zidentyfikowanych jest kilka kategorii:
- Replikowanie podstawowych optymalizacji, które istniały już w maszynie wirtualnej Java (JVM) i w wersji 8.
- Przez wykorzystanie wysoce zoptymalizowanych interfejsów API przeglądarek.
- Usuwanie wzorców kodowania JavaScript.
Po pierwsze, zespół Arkuszy musiał odtworzyć optymalizacje, które występują już w innych łańcuchach narzędzi. Najlepszym przykładem jest tu optymalizacja wysyłania metod wirtualnych, które od dawna jest optymalizowane przez JVM i V8, ale w przypadku WasmGC nie ma niczego takiego. Wdrożenie wbudowania spekulacyjnego i dewirtualizacji – 2 bardzo typowych optymalizacji – skróciło czas obliczeń w Chrome o około 40%.
Po drugie, w niektórych przypadkach interfejsy API w przeglądarce korzystają ze zoptymalizowanych implementacji natywnych, które trudno jest rywalizować z wykorzystaniem Wasm. Dobrymi przykładami są ciągi tekstowe i wyrażenia regularne. Wyrażenia regularne pozwalają nawet 100-krotnie przyspieszyć operacje związane z wyrażeniami regularnymi po przejściu z re2j (skompilowanego na WasmGC) na interfejs API przeglądarki RegExp
w Chrome, który może skompilować każde wyrażenie regularne do jego własnego kodu maszynowego.
Okazało się też, że wiele lat optymalizacji spowodowało, że baza kodu była nadmiernie dopasowana do JavaScriptu. Mieli na przykład podstawową strukturę danych w Arkuszach, w ramach której zacierały linie między tablicami a mapami. Jest to wydajne rozwiązanie w języku JavaScript, który automatycznie modeluje rozproszone tablice jako mapy, ale działa wolno na innych platformach. Musieliśmy więc zmodyfikować kod w sposób bardziej niezależny od platformy. Co więcej, w WebAssembly zespół lubi i chce, by aplikacje wieloplatformowe mogły sprawnie działać w internecie. Nie musisz zginać całej aplikacji zgodnie z idiosynchroniami języka JavaScript.
Ostateczny efekt
Po wszystkich optymalizacjach ostateczna wersja Arkuszy WasmGC generuje około 2 razy szybsze wyniki niż JavaScript, co oznacza 4-krotny wzrost w porównaniu z pierwotną wersją WasmGC.
Podsumowanie
WasmGC to zaawansowana technologia, która ma potencjał, aby usprawnić sposób, w jaki programiści tworzą aplikacje internetowe. Mamy nadzieję, że w najbliższych latach Google rozwinie funkcję WasmGC, aby wprowadzić obsługę wielowątkowości współdzielonej pamięci i jeszcze bardziej zwiększyć wydajność w pojedynczym wątku. Zachęcamy wszystkich twórców stron internetowych, aby rozważyli użycie WasmGC w przypadku kolejnych skutecznych projektów. Dołącz do nas i wspólnie spraw, by internet działał szybciej i sprawniej.
Podziękowania
Dziękuję za osoby, które pracowały nad implementacją WasmGC i to studium przypadku: Diwas Adhikary, Matthew Albright, Ksenia Bukina, Julien Dramaix, Goktug Gokdogan, Janice Gu, Adam Klein, Manos Koukos,