Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

W artykule omówiono przypadek przyspieszenia aplikacji przeglądarkowej poprzez zastąpienie obliczeń JavaScript modułem WebAssembly.

WebAssembly – co to jest?

Krótko mówiąc, jest to format instrukcji binarnych dla maszyny wirtualnej opartej na stosie. Wasm (nazwa krótka) jest często nazywany językiem programowania, ale tak nie jest. Format instrukcji wykonywany jest w przeglądarce wraz z JavaScriptem.

Ważne jest, aby WebAssembly można było uzyskać poprzez kompilację źródeł w językach takich jak C/C++, Rust, Go. Stosowane jest tu typowanie statystyczne i tzw. model płaskiej pamięci. Kod, jak wspomniano powyżej, jest przechowywany w kompaktowym formacie binarnym, dzięki czemu jest prawie tak szybki, jak uruchamianie aplikacji za pomocą wiersza poleceń. Możliwości te doprowadziły do ​​wzrostu popularności WebAssembly.

Przypomnienie: dla wszystkich czytelników „Habr” - rabat w wysokości 10 000 rubli przy zapisywaniu się na dowolny kurs Skillbox przy użyciu kodu promocyjnego „Habr”.

Skillbox poleca: Kurs praktyczny „Programista mobilny PRO”.

Obecnie Wasm jest używany w wielu aplikacjach, od gier takich jak Doom 3 po aplikacje internetowe, takie jak Autocad i Figma. Wasm jest również stosowany w takich obszarach jak przetwarzanie bezserwerowe.

W tym artykule przedstawiono przykład użycia Wasm do przyspieszenia usługi analitycznej. Dla przejrzystości wzięliśmy działającą aplikację napisaną w C, która jest wkompilowana do WebAssembly. Wynik zostanie wykorzystany do zastąpienia słabszych sekcji JS.

Transformacja aplikacji

W przykładzie wykorzystana zostanie usługa przeglądarki fastq.bio, która jest przeznaczona dla genetyków. Narzędzie pozwala ocenić jakość sekwencjonowania (rozszyfrowania) DNA.

Oto przykład aplikacji w akcji:

Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

Nie warto wdawać się w szczegóły tego procesu, gdyż są one dość skomplikowane dla niespecjalistów, ale w skrócie, naukowcy mogą wykorzystać powyższą infografikę, aby zrozumieć, czy proces sekwencjonowania DNA przebiegł sprawnie i jakie pojawiły się problemy.

Ta usługa ma alternatywy, programy komputerowe. Ale fastq.bio pozwala przyspieszyć pracę poprzez wizualizację danych. W większości innych przypadków musisz umieć pracować z wiersza poleceń, ale nie wszyscy genetycy mają niezbędne doświadczenie.

Wszystko działa po prostu. Dane wejściowe to dane prezentowane w formie pliku tekstowego. Plik ten jest generowany przez wyspecjalizowane narzędzia do sekwencjonowania. Plik zawiera listę sekwencji DNA i ocenę jakości dla każdego nukleotydu. Format pliku to .fastq i dlatego usługa ma swoją nazwę.

Implementacja w JavaScript

Pierwszym krokiem użytkownika podczas pracy z fastq.bio jest wybranie odpowiedniego pliku. Za pomocą obiektu File aplikacja odczytuje losową próbkę danych z pliku i przetwarza tę partię. Zadaniem JavaScriptu jest tutaj wykonywanie prostych operacji na ciągach znaków i obliczanie metryk. Jedną z nich jest liczba nukleotydów A, C, G i T na różnych fragmentach DNA.

Po obliczeniu niezbędnych wskaźników następuje ich wizualizacja za pomocą Plotly.js, a usługa zaczyna pracować z nową próbką danych. Porcjowanie ma na celu poprawę jakości UX. Jeśli będziesz pracować ze wszystkimi danymi na raz, proces zostanie na pewien czas zatrzymany, ponieważ pliki z wynikami sekwencjonowania zajmują setki gigabajtów miejsca. Usługa pobiera fragmenty danych o wielkości od 0,5 do 1 MB i krok po kroku pracuje z nimi, budując dane graficzne.

Tak to działa:

Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

Czerwony prostokąt zawiera algorytm transformacji ciągu w celu uzyskania wizualizacji. Jest to najbardziej wymagająca obliczeniowo część usługi. Warto spróbować zastąpić go Wasmem.

Testowanie zestawu WebAssembly

Aby ocenić możliwość wykorzystania Wasm, zespół projektowy rozpoczął poszukiwania gotowych rozwiązań do tworzenia metryk QC (QC - kontrola jakości) w oparciu o pliki fastq. Poszukiwania przeprowadzono wśród narzędzi napisanych w C, C++ lub Rust, tak aby możliwe było przeniesienie kodu do WebAssembly. Poza tym narzędzie nie powinno być „surowe”, potrzebna była usługa, która została już przetestowana przez naukowców.

W rezultacie wybór został dokonany na korzyść nast. Aplikacja jest dość popularna, jest open-source, językiem źródłowym jest C.

Przed konwersją do Wasm warto przyjrzeć się zasadzie kompilacji seqtk na komputery stacjonarne. Według Makefile oto, czego potrzebujesz:

# Compile to binary
$ gcc seqtk.c 
   -o seqtk 
   -O2 
   -lm 
   -lz

Zasadniczo możesz skompilować seqtk za pomocą Emscripten. Jeśli go tam nie ma, radzimy sobie. Obraz Dockera.

$ docker pull robertaboukhalil/emsdk:1.38.26
$ docker run -dt --name wasm-seqtk robertaboukhalil/emsdk:1.38.26

Jeśli jest to pożądane, Możesz go złożyć samodzielnie, ale to wymaga czasu.

Wewnątrz kontenera możesz z łatwością użyć emcc jako alternatywy dla gcc:

# Compile to WebAssembly
$ emcc seqtk.c 
    -o seqtk.js 
    -O2 
    -lm 
    -s USE_ZLIB=1 
    -s FORCE_FILESYSTEM=1

Minimalne zmiany:

Zamiast wysyłać dane do pliku binarnego, Emscripten używa plików .wasm i .js do generowania plików, które służą do uruchamiania modułu WebAssemby.

Flaga USE_ZLIB służy do obsługi biblioteki zlib. Biblioteka została rozesłana i przeniesiona do WebAssembly, a Emscripten włącza ją do projektu.

Aktywowany jest wirtualny system plików Emscrippten. Ten FS podobny do POSIX, działający w pamięci RAM przeglądarki. Po odświeżeniu strony pamięć zostaje wyczyszczona.

Aby zrozumieć, dlaczego potrzebny jest wirtualny system plików, warto porównać sposób uruchamiania seqtk z wiersza poleceń ze sposobem uruchamiania skompilowanego modułu WebAssembly.

# On the command line
$ ./seqtk fqchk data.fastq
 
# In the browser console
> Module.callMain(["fqchk", "data.fastq"])

Uzyskanie dostępu do wirtualnego systemu plików jest konieczne, aby nie przepisywać seqtk dla łańcucha zamiast wprowadzania danych do pliku. W tym przypadku fragment danych jest wyświetlany jako plik data.fastq w wirtualnym systemie plików z wywołaniem funkcji main() seqtk.

Oto nowa architektura:

Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

Рисунок демонстрирует, что вместо вычислений в основном потоке браузера используется Pracownicy sieciowi. Ta metoda umożliwia wykonywanie obliczeń w wątku w tle bez wpływu na responsywność przeglądarki. Cóż, kontroler WebWorker uruchamia Workera, zarządzając jego interakcją z głównym wątkiem.

Komenda seqtk jest uruchamiana przy użyciu procesu roboczego na zamontowanym pliku. Po zakończeniu realizacji Robotnik generuje wynik w postaci Obietnicy. Po odebraniu wiadomości przez główny wątek wynik jest używany do aktualizacji wykresów. I tak dalej w kilku iteracjach.

A co z wydajnością zestawu WebAssembly?

Aby ocenić zmianę wydajności, zespół projektowy wykorzystał parametr operacji odczytu na sekundę. Czas potrzebny na zbudowanie interaktywnych wykresów nie jest brany pod uwagę, ponieważ obie implementacje korzystają z JavaScript.

Przy zastosowaniu gotowego rozwiązania wzrost wydajności był dziewięciokrotny.

Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

To znakomity wynik, ale – jak się okazuje – jest też szansa na jego optymalizację. Faktem jest, że duża liczba wyników analizy QC nie jest wykorzystywana przez seqtk, więc można je usunąć. Jeśli to zrobisz, wynik poprawi się 13 razy w porównaniu do JS.

Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

Osiągnięto to poprzez proste skomentowanie poleceń printf().

Ale to nie wszystko. Faktem jest, że na tym etapie fastq.bio otrzymuje wyniki analizy, wywołując różne funkcje C. Każda z nich oblicza swój własny zestaw cech, dzięki czemu każdy fragment pliku jest czytany dwukrotnie.

Aby obejść ten problem, zdecydowano się połączyć dwie funkcje w jedną. W rezultacie produktywność wzrosła 20-krotnie.

Jak wykorzystaliśmy WebAssembly do 20-krotnego przyspieszenia aplikacji internetowej

Warto zaznaczyć, że nie zawsze udaje się osiągnąć tak znakomity wynik. W niektórych przypadkach wydajność spadnie, dlatego warto ocenić każdy przypadek.

Podsumowując, możemy stwierdzić, że Wasm rzeczywiście daje szansę na poprawę wydajności aplikacji, ale trzeba z niej mądrze korzystać.

Skillbox poleca:

Źródło: www.habr.com

Dodaj komentarz