
In diesem Artikel wird ein Fallbeispiel zur Beschleunigung einer Browseranwendung durch den Austausch von JavaScript-Berechnungen gegen WebAssembly betrachtet.
Was ist WebAssembly?
Kurz gesagt, es handelt sich um ein binĂ€res Format von Instruktionen fĂŒr eine Stack-Virtual-Machine. Oft wird Wasm (abgekĂŒrzt) als Programmiersprache bezeichnet, was jedoch nicht korrekt ist. Das Instruktionsformat wird im Browser neben JavaScript ausgefĂŒhrt.
Wichtig ist, dass WebAssembly durch die Kompilierung von Quellcode in Sprachen wie C/C++, Rust und Go erzeugt werden kann. Hier wird statische Typisierung und das sogenannte flache Speicher-Modell verwendet. Der Code, wie oben erwĂ€hnt, wird in einem kompakten binĂ€ren Format gespeichert, was dazu fĂŒhrt, dass er fast genauso schnell ausgefĂŒhrt wird, als ob die Anwendung ĂŒber die Kommandozeile gestartet worden wĂ€re. Diese Möglichkeiten haben zur zunehmenden Beliebtheit von WebAssembly gefĂŒhrt.
Wir erinnern daran: alle Leser von âHabrâ erhalten einen Rabatt von 10.000 Rubel bei der Anmeldung zu einem beliebigen Kurs von Skillbox mit dem Aktionscode âHabrâ.
Skillbox empfiehlt: Praktischer Kurs .
Derzeit wird Wasm in vielen Anwendungen eingesetzt, von Spielen wie Doom 3 bis hin zu webbasierten Anwendungen wie Autocad und Figma. Wasm findet auch in Bereichen wie serverless Computing Anwendung.
In diesem Artikel wird ein Beispiel fĂŒr die Verwendung von Wasm zur Beschleunigung eines analytischen Webdienstes gegeben. Zur Veranschaulichung haben wir eine funktionierende Anwendung in C genommen, die nach WebAssembly kompiliert wird. Das Ergebnis wird verwendet, um leistungsschwache Bereiche von JS zu ersetzen.
Transformation der Anwendung
Im Beispiel wird der Browserdienst fastq.bio verwendet, der fĂŒr Genetiker gedacht ist. Das Werkzeug ermöglicht die Bewertung der SequenzierqualitĂ€t (EntschlĂŒsselung) von DNA.
Hier ist ein Beispiel fĂŒr eine laufende Anwendung:

Die Einzelheiten des Prozesses mĂŒssen nicht erlĂ€utert werden, da sie fĂŒr Laien recht kompliziert sind, aber zusammengefasst können die Wissenschaftler anhand der obigen Infografik feststellen, ob der DNA-Sequenzierungsprozess reibungslos verlaufen ist und welche Probleme aufgetreten sind.
Dieser Dienst hat Alternativen, Desktop-Programme. Aber fastq.bio ermöglicht eine Beschleunigung der Arbeit, indem es die Daten visualisiert. In den meisten anderen FÀllen muss man mit der Kommandozeile umgehen können, was nicht alle Genetiker können.
Es funktioniert ganz einfach. Am Eingang stehen Daten, die in Form einer Textdatei vorliegen. Diese Datei wird von speziellen Sequenzierungswerkzeugen generiert. In der Datei befindet sich eine Liste von DNA-Sequenzen und die QualitĂ€tsbewertung fĂŒr jedes Nukleotid. Das Dateiformat ist .fastq, daher erhielt der Dienst diesen Namen.
Implementierung in JavaScript
Der erste Schritt des Benutzers bei der Arbeit mit fastq.bio ist die Auswahl der entsprechenden Datei. Mit dem File-Objekt liest die Anwendung eine zufĂ€llige Stichprobe der Daten aus der Datei und verarbeitet dieses Paket. Die Aufgabe von JavaScript besteht hierbei darin, einfache String-Operationen auszufĂŒhren und Kennzahlen zu berechnen. Eine dieser Kennzahlen ist die Anzahl der Nukleotide A, C, G und T in verschiedenen DNA-Fragmenten.
Nach der Berechnung der erforderlichen Kennzahlen werden diese mithilfe von Plotly.js visualisiert, und der Dienst beginnt mit einer neuen Datenstichprobe. Die Segmentierung wurde vorgenommen, um die QualitĂ€t der Benutzererfahrung zu verbessern. Wenn man mit allen Daten auf einmal arbeitet, kann der Prozess eine Weile hĂ€ngen bleiben, da die Sequenzierungsergebnisse Hunderte von Gigabytes Speicherplatz benötigen. Der Dienst nimmt stattdessen Datenabschnitte von 0,5 bis 1 MB und bearbeitet sie Schritt fĂŒr Schritt und erstellt grafische Daten.
So funktioniert es:

Im roten Rechteck befindet sich der Algorithmus fĂŒr String-Transformationen zur Erstellung der Visualisierung. Dies ist der rechenintensivste Teil des Dienstes. Es lohnt sich, zu versuchen, ihn durch Wasm zu ersetzen.
WebAssembly testen
Um die Möglichkeit der Nutzung von Wasm zu bewerten, begab sich das Projektteam auf die Suche nach fertigen Lösungen zur Erzeugung einer QC-Metrik (QC â quality control) basierend auf fastq-Dateien. Die Suche erfolgte unter Werkzeugen, die in C, C++ oder Rust geschrieben wurden, um den Code auf WebAssembly portieren zu können. DarĂŒber hinaus sollte das Werkzeug nicht ârohâ sein, ein bereits von Wissenschaftlern getesteter Dienst wurde benötigt.
Infolgedessen fiel die Wahl auf . Die Anwendung ist recht populÀr, sie ist Open Source und die Ausgangsprache ist C.
Vor der Umwandlung in Wasm sollte man sich das Kompilierungsprinzip von seqtk fĂŒr den Desktop ansehen. Laut Makefile ist Folgendes erforderlich:
# Compile to binary
$ gcc seqtk.c
-o seqtk
-O2
-lm
-lzIm Prinzip kann seqtk mit Emscripten kompiliert werden. Wenn dies nicht verfĂŒgbar ist, kommt man .
$ docker pull robertaboukhalil\/emsdk:1.38.26
$ docker run -dt --name wasm-seqtk robertaboukhalil\/emsdk:1.38.26Wenn gewĂŒnscht, , aber das erfordert Zeit.
Innerhalb des Containers kann problemlos emcc als Alternative zu gcc verwendet werden:
# Compile to WebAssembly
$ emcc seqtk.c
-o seqtk.js
-O2
-lm
-s USE_ZLIB=1
-s FORCE_FILESYSTEM=1Minimale Ănderungen:
Anstelle der Ausgabe in eine BinÀrdatei wird Emscripten verwendet, um .wasm- und .js-Dateien zu generieren, die zum Starten des WebAssembly-Moduls verwendet werden.
FĂŒr die UnterstĂŒtzung der zlib-Bibliothek wird das Flag USE_ZLIB verwendet. Die Bibliothek ist verbreitet und auf WebAssembly portiert, und Emscripten schlieĂt sie in das Projekt ein.
Die virtuelle Dateiensystem Emscripten wird aktiviert. Dies ist , die im Arbeitsspeicher innerhalb des Browsers funktioniert. Wenn die Seite aktualisiert wird, wird der Speicher gelöscht.
Um zu verstehen, warum ein virtuelles Dateisystem erforderlich ist, sollte man den Start von seqtk ĂŒber die Kommandozeile mit dem Start des kompilierte WebAssembly-Moduls vergleichen.
# On the command line
$ ./seqtk fqchk data.fastq
# In the browser console
> Module.callMain(["fqchk", "data.fastq"])Der Zugriff auf das virtuelle Dateisystem ist notwendig, um seqtk nicht fĂŒr den Zeichen- statt Datei-Input umschreiben zu mĂŒssen. In diesem Fall wird der Datenausschnitt als Datei data.fastq im virtuellen FS angezeigt, mit einem Aufruf von main() seqtk.
Hier ist die neue Architektur:

Die Abbildung zeigt, dass anstelle von Berechnungen im Haupt-Thread des Browsers verwendet werden. Dieses Verfahren ermöglicht es, Berechnungen im Hintergrund-Thread durchzufĂŒhren, ohne die ReaktionsfĂ€higkeit des Browsers zu beeintrĂ€chtigen. Der WebWorker-Controller startet den Worker und verwaltet dessen Interaktion mit dem Haupt-Thread.
Der seqtk-Befehl wird mit Hilfe eines Workers auf der gemounteten Datei gestartet. Nach Abschluss der AusfĂŒhrung gibt der Worker das Ergebnis als Promise aus. Wenn die Nachricht im Haupt-Thread empfangen wird, wird das Ergebnis verwendet, um die Diagramme zu aktualisieren. Und so in mehreren Iterationen.
Wie steht es um die Leistung von WebAssembly?
Um die LeistungsĂ€nderung zu bewerten, hat das Projektteam den Parameter der Anzahl der Leseoperationen pro Sekunde verwendet. Die Zeit fĂŒr die Erstellung interaktiver Diagramme wird nicht berĂŒcksichtigt, da in beiden Implementierungen JavaScript verwendet wird.
Bei der Verwendung der 'Out-of-the-Box'-Lösung betrug der Leistungsgewinn das Neunfache.

Das ist ein hervorragendes Ergebnis, aber wie sich herausstellte, besteht die Möglichkeit, es weiter zu optimieren. TatsÀchlich werden viele der QC-Analyseergebnisse von seqtk nicht verwendet, sodass sie entfernt werden können. Wenn dies geschieht, verbessert sich das Ergebnis im Vergleich zu JS um das 13-fache.

Dies wurde erreicht, indem einfach die printf()-Befehle kommentiert wurden.
Aber das ist noch nicht alles. TatsÀchlich erhÀlt fastq.bio in diesem Stadium die Analyseergebnisse durch den Aufruf verschiedener Funktionen in C. Jede von ihnen berechnet ihren eigenen Satz von Merkmalen, sodass jeder Dateifragmente zweimal gelesen wurde.
Um dieses Problem zu umgehen, wurde beschlossen, zwei Funktionen in einer zu kombinieren. Dies fĂŒhrte zu einer 20-fachen Leistungssteigerung.

Es ist erwÀhnenswert, dass ein so herausragendes Ergebnis nicht immer erreicht werden kann. In einigen FÀllen sinkt die Leistung, sodass jede spezifische Situation bewertet werden sollte.
Zusammenfassend lÀsst sich sagen, dass WebAssembly tatsÀchlich die Möglichkeit bietet, die Anwendungsleistung zu verbessern, aber man sollte es mit Bedacht einsetzen.
Skillbox empfiehlt:
- ZweijÀhriger praktischer Kurs .
- Online-Kurs .
- Praktischer Jahreskurs .
Quelle: habr.com
