Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

V tomto článku se zkoumá případ urychlení webové aplikace nahrazením JavaScriptových výpočtů WebAssembly.

Co je to WebAssembly?

Stručně řečeno, je to binární formát instrukcí pro zásobníkovou virtuální stroj. Často je označován jako programovací jazyk, ale není tomu tak. Formát instrukcí se vykonává v prohlížeči vedle JavaScriptu.

Je důležité, že WebAssembly lze získat kompilací zdrojových kódů v takových jazycích jako C/C++, Rust, Go. Používá se zde statická typizace a takzvaný plochý model paměti. Kód, jak bylo uvedeno výše, je uložen v kompaktním binárním formátu, díky čemuž je vykonáván téměř stejně rychle, jako by byla aplikace spuštěna pomocí příkazového řádku. Tyto možnosti vedly k růstu popularity WebAssembly.

Připomínáme: pro všechny čtenáře "Habra" – sleva 10 000 korun při registraci na jakýkoli kurz Skillbox s promokódem "Habr".

Skillbox doporučuje: Praktický kurz "Mobilní vývojář PRO".

V současné době se Wasm používá v mnoha aplikacích, od her jako Doom 3 po portované webové aplikace jako Autocad a Figma. Wasm je také používán v oblasti serverless výpočtů.

V tomto článku je uveden příklad použití Wasm pro urychlení analytického webového služby. Pro názornost jsme vybrali fungující aplikaci napsanou v C, která bude zkompilována do WebAssembly. Výsledek bude použit k nahrazení málo výkonných částí JS.

Transformace aplikace

V příkladu bude použit prohlížečový servis fastq.bio, který je určen pro genetiky. Nástroj umožňuje vyhodnotit kvalitu sekvenování (dešifrování) DNA.

Zde je příklad aplikace v akci:

Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

Podrobnosti procesu není třeba uvádět, protože jsou docela složité pro nespecialisty, ale zjednodušeně řečeno, vědci podle uvedené infografiky mohou pochopit, zda proběhl proces sekvenování DNA hladce a jaké problémy se vyskytly.

Tento servis má alternativy, desktopové programy. Ale fastq.bio umožňuje zrychlit práci vizualizací dat. Většina ostatních případů vyžaduje umět pracovat s příkazovým řádkem, ale ne všichni genetikové mají potřebné zkušenosti.

Všechno funguje jednoduše. Na vstupu jsou údaje, které jsou prezentovány ve formě textového souboru. Tento soubor je generován specializovanými nástroji pro sekvenování. V souboru je uveden seznam sekvencí DNA a hodnocení kvality pro každý nukleotid. Formát souboru je .fastq, takže služba dostala toto jméno.

Implementace v JavaScriptu

První krok uživatele při práci s fastq.bio je výběr příslušného souboru. Pomocí objektu File aplikace čte náhodný vzorek dat ze souboru a zpracovává tento balíček. Úkol JavaScriptu zde spočívá v provádění jednoduchých operací se stringy a počítání ukazatelů. Jedním z nich je počet nukleotidů A, C, G a T v různých fragmentech DNA.

Po výpočtu potřebných ukazatelů jsou vizualizovány pomocí Plotly.js a služba začíná pracovat s novým vzorkem dat. Rozdělení na fragmenty je provedeno pro zvýšení kvality uživatelského zážitku. Pokud bychom pracovali se všemi daty najednou, proces by na nějakou dobu uvíznul, protože soubory se sekvenačními výsledky zabírají stovky gigabajtů diskového prostoru. Služba však bere úseky dat o velikosti od 0,5 do 1 MB a pracuje s nimi krok za krokem, vytvářejíc grafická data.

Jak to funguje:

Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

V červeném obdélníku je umístěn algoritmus pro stringové transformace pro získání vizualizace. To je nejvýpočetně náročnější část služby. Stojí za to ji zkusit nahradit Wasm.

Testujeme WebAssembly

Pro hodnocení možnosti použití Wasm se tým projektu zabýval hledáním hotových řešení pro vytvoření metriky QC (QC — quality control) na základě souborů fastq. Hledání probíhalo mezi nástroji napsanými v C, C++ nebo Rust, aby bylo možné portovat kód do WebAssembly. Kromě toho by nástroj neměl být "syrový", bylo potřeba, aby byl služba již ověřená vědci.

V důsledku toho byla učiněna volba ve prospěch seqtk. Aplikace je docela populární, je open-source a původní jazyk je C.

Před převodem na Wasm stojí za to se podívat na princip kompilace seqtk pro desktop. Podle Makefile, zde je to, co potřebujete:

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

V zásadě lze seqtk zkompilovat pomocí Emscripten. Pokud ho nemáte, obejdeme se takto: Docker.

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

Při přání ho lze sestavit i samostatně, ale to zabere čas.

Uvnitř kontejneru lze bez problémů použít emcc jako alternativu gcc:

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

Minimální změny:

Namísto výstupu do binárního souboru Emscripten generuje soubory ve formátu .wasm a .js, který se používá k spuštění modulu WebAssembly.

Pro podporu knihovny zlib se používá flag USE_ZLIB. Knihovna je rozšířená a portována na WebAssembly, a Emscripten ji zahrnuje do projektu.

Aktivuje se virtuální souborový systém Emscripten. To je POSIX-podobný FS, který funguje v paměti uvnitř prohlížeče. Když se stránka aktualizuje, paměť se vymaže.

Abychom pochopili, proč je potřeba virtuální souborový systém, je dobré srovnat způsob spuštění seqtk z příkazové řádky se způsobem spuštění zkompilovaného modulu WebAssembly.

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

Získání přístupu k virtuálnímu souborovému systému je nutné, abychom nemuseli přepracovávat seqtk pro vstup ze standardního vstupu místo ze souboru. V takovém případě se fragment dat zobrazuje jako soubor data.fastq ve virtuálním FS s voláním main() seqtk.

Zde je nová architektura:

Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

Obrázek ukazuje, že místo výpočtů v hlavním vlákně prohlížeče se používají WebWorkers. Tento způsob umožňuje provádět výpočty na pozadí, aniž by se zhoršila odezva prohlížeče. Kontroler WebWorker spouští Worker a řídí jeho interakci s hlavním vláknem.

Příkaz seqtk se spouští pomocí Worker na připojeném souboru. Po dokončení úlohy Worker vrací výsledek ve formě Promise. Když hlavní vlákno obdrží zprávu, výsledek se využívá k aktualizaci grafů. A tak to probíhá v několika iteracích.

Jak je to s výkonem WebAssembly?

Abychom posoudili změnu výkonu, tým projektu použil parametr počtu operací čtení za sekundu. Čas potřebný k vytvoření interaktivních grafů se nezapočítává, protože v obou implementacích se používá JavaScript.

Při použití řešení „out of the box“ došlo ke zvýšení výkonu o devětkrát.

Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

To je skvělý výsledek, ale jak se ukázalo, existuje možnost ho optimalizovat. Množství výsledků QC analýzy používaných seqtk není nezbytné, takže je lze odstranit. Pokud to uděláte, výsledky v porovnání s JS se zlepšují třináctinásobně.

Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

Toho bylo dosaženo jednoduše zakomentováním příkazů printf().

Ale to není všechno. Skutečností je, že v této fázi fastq.bio získává výsledky analýzy pomocí volání různých funkcí C. Každá z nich vypočítává svůj soubor vlastností, takže každý fragment souboru byl přečten dvakrát.

Abychom vyřešili tento problém, rozhodli jsme se sloučit dvě funkce do jedné. Výsledkem bylo dvacetinásobné zvýšení výkonu.

Jak jsme pomocí WebAssembly urychlili webovou aplikaci 20krát

Je třeba poznamenat, že takového vynikajícího výsledku nelze dosáhnout vždy. V některých případech výkon klesá, takže je nutné posuzovat každý konkrétní případ.

Na závěr lze říci, že Wasm skutečně umožňuje zlepšit výkon aplikace, ale je třeba jej používat s rozumem.

Skillbox doporučuje:

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster