Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Den här artikeln diskuterar ett fall för att påskynda en webbläsarapplikation genom att ersätta JavaScript-beräkningar med WebAssembly.

WebAssembly - vad är det?

Kort sagt är detta ett binärt instruktionsformat för en stackbaserad virtuell maskin. Wasm (kort namn) kallas ofta för ett programmeringsspråk, men det är det inte. Instruktionsformatet körs i webbläsaren tillsammans med JavaScript.

Det är viktigt att WebAssembly kan erhållas genom att sammanställa källor på språk som C/C++, Rust, Go. Här används statistisk typning och den så kallade plattminnesmodellen. Koden, som nämnts ovan, lagras i ett kompakt binärt format, vilket gör det nästan lika snabbt som att köra programmet med kommandoraden. Dessa funktioner har lett till att WebAssemblys popularitet har ökat.

Påminnelse: för alla läsare av "Habr" - en rabatt på 10 000 rubel när du anmäler dig till någon Skillbox-kurs med hjälp av "Habr"-kampanjkoden.

Skillbox rekommenderar: Praktisk kurs "Mobilutvecklare PRO".

För närvarande används Wasm i många applikationer, från spel som Doom 3 till webbporterade applikationer som Autocad och Figma. Wasm används också inom områden som serverlös datoranvändning.

Den här artikeln ger ett exempel på hur man använder Wasm för att snabba upp en analyswebbtjänst. För tydlighetens skull tog vi en fungerande applikation skriven i C, som kompileras till WebAssembly. Resultatet kommer att användas för att ersätta underpresterande delar av JS.

Application Transformation

Exemplet kommer att använda webbläsartjänsten fastq.bio, som är avsedd för genetiker. Verktyget låter dig utvärdera kvaliteten på DNA-sekvensering (dechiffrering).

Här är ett exempel på applikationen i aktion:

Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Detaljerna i processen är inte värda att gå in på eftersom de är ganska komplexa för icke-specialister, men kort sagt kan forskare använda infografiken ovan för att förstå om DNA-sekvenseringsprocessen gick smidigt och vilka problem som uppstod.

Denna tjänst har alternativ, skrivbordsprogram. Men fastq.bio låter dig påskynda ditt arbete genom att visualisera data. I de flesta andra fall måste du kunna arbeta med kommandoraden, men alla genetiker har inte den erfarenhet som krävs.

Allt fungerar helt enkelt. Indata är data som presenteras i form av en textfil. Denna fil genereras av specialiserade sekvenseringsverktyg. Filen innehåller en lista med DNA-sekvenser och en kvalitetspoäng för varje nukleotid. Filformatet är .fastq, vilket är anledningen till att tjänsten fick sitt namn.

Implementering i JavaScript

Det första steget för användaren när han arbetar med fastq.bio är att välja lämplig fil. Med hjälp av File-objektet läser programmet ett slumpmässigt urval av data från en fil och bearbetar den batchen. JavaScripts jobb här är att utföra enkla strängoperationer och beräkna mätvärden. En av dem är antalet nukleotider A, C, G och T på olika DNA-fragment.

Efter att ha beräknat de nödvändiga indikatorerna visualiseras de med Plotly.js, och tjänsten börjar arbeta med ett nytt dataprov. Chunkingen görs för att förbättra kvaliteten på UX. Om du arbetar med all data på en gång kommer processen att frysa under en tid, eftersom filerna med sekvenseringsresultaten tar upp hundratals gigabyte filutrymme. Tjänsten tar bitar av data i storlek från 0,5 till 1 MB och arbetar med dem steg för steg och bygger grafisk data.

Вот как это работает:

Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Den röda rektangeln innehåller strängtransformationsalgoritmen för att erhålla visualisering. Detta är den mest beräkningsintensiva delen av tjänsten. Det är värt att försöka ersätta den med Wasm.

Testar WebAssembly

För att bedöma möjligheten att använda Wasm började projektgruppen söka efter färdiga lösningar för att skapa QC-mått (QC - kvalitetskontroll) baserade på fastq-filer. Sökningen utfördes bland verktyg skrivna i C, C++ eller Rust, så att det var möjligt att porta koden till WebAssembly. Dessutom bör verktyget inte vara "rå"; en tjänst som redan hade testats av forskare krävdes.

Som ett resultat gjordes valet till förmån för seqtk. Applikationen är ganska populär, den är öppen källkod, källspråket är C.

Innan du konverterar till Wasm är det värt att titta på kompileringsprincipen för seqtk för skrivbordet. Enligt Makefile, här är vad du behöver:

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

I princip kan du kompilera seqtk med Emscripten. Finns den inte där så klarar vi oss. Docker-bild.

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

Om så önskas, Du kan montera den självmen det tar tid.

Inuti en behållare kan du enkelt använda emcc som ett alternativ till gcc:

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

Minsta ändringar:

Istället för att mata ut till en binär fil använder Emscripten .wasm och .js för att generera filerna, som används för att köra WebAssemby-modulen.

USE_ZLIB-flaggan används för att stödja zlib-biblioteket. Biblioteket har distribuerats och porterats till WebAssembly, och Emscripten inkluderar det i projektet.

Emscripptens virtuella filsystem är aktiverat. Detta POSIX-liknande FS, körs i RAM i webbläsaren. När sidan har uppdaterats rensas minnet.

För att förstå varför ett virtuellt filsystem behövs är det värt att jämföra hur du kör seqtk från kommandoraden med hur du kör en kompilerad WebAssembly-modul.

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

Att få tillgång till det virtuella filsystemet är nödvändigt för att inte skriva om seqtk för sträng snarare än filinmatning. I det här fallet visas datafragmentet som en data.fastq-fil i den virtuella FS med ett anrop till main() seqtk.

Här är den nya arkitekturen:

Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Figuren visar att istället för beräkningar i huvudwebbläsartråden, WebWorkers. Den här metoden låter dig utföra beräkningar i en bakgrundstråd utan att påverka webbläsarens respons. Jo, WebWorker-kontrollern startar Worker och hanterar dess interaktion med huvudtråden.

Kommandot seqtk körs med Worker på den monterade filen. Efter avslutad avrättning producerar Arbetaren ett resultat i form av ett löfte. När ett meddelande tas emot av huvudtråden används resultatet för att uppdatera graferna. Och så vidare i flera iterationer.

Hur är det med WebAssembly-prestanda?

För att utvärdera förändringen i prestanda använde projektgruppen parametern läsoperationer per sekund. Den tid det tar att bygga interaktiva grafer tas inte med i beräkningen eftersom båda implementeringarna använder JavaScript.

När man använde den färdiga lösningen var prestandaökningen nio gånger.

Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Detta är ett utmärkt resultat, men som det visar sig finns det en möjlighet att optimera det också. Faktum är att ett stort antal QC-analysresultat inte används av seqtk, så de kan raderas. Om du gör detta förbättras resultatet med 13 gånger jämfört med JS.

Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Det uppnåddes genom att helt enkelt kommentera printf()-kommandona.

Men det är inte allt. Faktum är att i detta skede tar fastq.bio emot analysresultaten genom att anropa olika C-funktioner. Var och en av dem beräknar sin egen uppsättning egenskaper, så att varje fragment av filen läses två gånger.

För att komma runt detta problem beslöt man att kombinera två funktioner till en. Som ett resultat ökade produktiviteten med 20 gånger.

Hur vi använde WebAssembly för att snabba upp en webbapplikation 20 gånger

Det är värt att notera att ett sådant enastående resultat inte alltid kan uppnås. I vissa fall kommer prestandan att sjunka, så det är värt att utvärdera varje fall.

Som en slutsats kan vi säga att Wasm ger en möjlighet att förbättra applikationsprestanda, men du måste använda den på ett klokt sätt.

Skillbox rekommenderar:

Källa: will.com

Lägg en kommentar