Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

Aquest article tracta un cas per accelerar una aplicació de navegador substituint els càlculs de JavaScript per WebAssembly.

WebAssembly: què és?

En resum, aquest és un format d'instrucció binària per a una màquina virtual basada en pila. Wasm (nom curt) sovint s'anomena llenguatge de programació, però no ho és. El format d'instrucció s'executa al navegador juntament amb JavaScript.

És important que WebAssembly es pugui obtenir compilant fonts en llenguatges com C/C++, Rust, Go. Aquí s'utilitza la tipografia estadística i l'anomenat model de memòria plana. El codi, com s'ha esmentat anteriorment, s'emmagatzema en un format binari compacte, el que fa que sigui gairebé tan ràpid com executar l'aplicació mitjançant la línia d'ordres. Aquestes capacitats han donat lloc al creixement de la popularitat de WebAssembly.

Recordem: per a tots els lectors de "Habr": un descompte de 10 rubles en inscriure's a qualsevol curs de Skillbox amb el codi promocional "Habr".

Skillbox recomana: Curs pràctic "Desenvolupador mòbil PRO".

Actualment, Wasm s'utilitza en moltes aplicacions, des de jocs com Doom 3 fins a aplicacions portades a la web com Autocad i Figma. Wasm també s'utilitza en àrees com la informàtica sense servidor.

Aquest article proporciona un exemple d'ús de Wasm per accelerar un servei web d'anàlisi. Per a més claredat, vam agafar una aplicació de treball escrita en C, que es compila a WebAssembly. El resultat s'utilitzarà per substituir seccions de baix rendiment de JS.

Transformació d'aplicacions

L'exemple utilitzarà el servei de navegador fastq.bio, destinat a genetistes. L'eina permet avaluar la qualitat de la seqüenciació de l'ADN (desxifrat).

Aquí teniu un exemple de l'aplicació en acció:

Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

No val la pena entrar en els detalls del procés, ja que són força complexos per als no especialistes, però en resum, els científics poden utilitzar la infografia anterior per entendre si el procés de seqüenciació de l'ADN va anar bé i quins problemes van sorgir.

Aquest servei té alternatives, programes d'escriptori. Però fastq.bio us permet accelerar el vostre treball visualitzant les dades. En la majoria dels altres casos, heu de poder treballar amb la línia d'ordres, però no tots els genetistes tenen l'experiència necessària.

Tot funciona simplement. L'entrada són dades presentades en forma d'arxiu de text. Aquest fitxer es genera amb eines de seqüenciació especialitzades. El fitxer conté una llista de seqüències d'ADN i una puntuació de qualitat per a cada nucleòtid. El format del fitxer és .fastq, per això el servei va rebre el seu nom.

Implementació en JavaScript

El primer pas de l'usuari quan treballa amb fastq.bio és seleccionar el fitxer adequat. Mitjançant l'objecte Fitxer, l'aplicació llegeix una mostra aleatòria de dades d'un fitxer i processa aquest lot. La feina de JavaScript aquí és realitzar operacions senzilles de cadena i calcular mètriques. Un d'ells és el nombre de nucleòtids A, C, G i T en diferents fragments d'ADN.

Després de calcular els indicadors necessaris, es visualitzen mitjançant Plotly.js i el servei comença a funcionar amb una nova mostra de dades. La fragmentació es fa per millorar la qualitat de l'UX. Si treballeu amb totes les dades alhora, el procés es congelarà durant un temps, ja que els fitxers amb els resultats de la seqüenciació ocupen centenars de gigabytes d'espai. El servei pren peces de dades que van de 0,5 a 1 MB i treballa amb elles pas a pas, creant dades gràfiques.

Així funciona:

Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

El rectangle vermell conté l'algorisme de transformació de cadena per obtenir la visualització. Aquesta és la part del servei amb més càlcul. Val la pena intentar substituir-lo per Wasm.

Prova de WebAssembly

Per avaluar la possibilitat d'utilitzar Wasm, l'equip del projecte va començar a buscar solucions ja fetes per crear mètriques de QC (QC - control de qualitat) basades en fitxers fastq. La cerca es va fer entre eines escrites en C, C++ o Rust, de manera que es va poder portar el codi a WebAssembly. A més, l'eina no hauria de ser "crua"; calia un servei que ja havia estat provat pels científics.

Com a resultat, l'elecció es va fer a favor seqtk. L'aplicació és força popular, és de codi obert, l'idioma font és C.

Abans de convertir a Wasm, val la pena mirar el principi de compilació de seqtk per a l'escriptori. Segons el Makefile, aquí teniu el que necessiteu:

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

En principi, podeu compilar seqtk amb Emscripten. Si no hi és, ho fem. Imatge de Docker.

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

Si es desitja, Podeu muntar-lo vosaltres mateixos, però requereix temps.

Dins d'un contenidor, podeu utilitzar fàcilment emcc com a alternativa a gcc:

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

Canvis mínims:

En lloc de sortir a un fitxer binari, Emscripten utilitza .wasm i .js per generar els fitxers, que s'utilitza per executar el mòdul WebAssemby.

El senyalador USE_ZLIB s'utilitza per donar suport a la biblioteca zlib. La biblioteca s'ha distribuït i portat a WebAssembly, i Emscripten la inclou al projecte.

El sistema de fitxers virtual d'Emscriptpten està activat. Això FS semblant a POSIX, que s'executa a la memòria RAM dins del navegador. Quan s'actualitza la pàgina, la memòria s'esborra.

Per entendre per què es necessita un sistema de fitxers virtual, val la pena comparar la manera d'executar seqtk des de la línia d'ordres amb la manera d'executar un mòdul WebAssembly compilat.

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

És necessari obtenir accés al sistema de fitxers virtual per no reescriure seqtk per a la cadena en lloc de l'entrada del fitxer. En aquest cas, el fragment de dades es mostra com un fitxer data.fastq al FS virtual amb una crida a main() seqtk.

Aquí teniu la nova arquitectura:

Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

La figura mostra que en lloc dels càlculs al fil del navegador principal, WebWorkers. Aquest mètode us permet realitzar càlculs en un fil de fons sense afectar la capacitat de resposta del navegador. Bé, el controlador WebWorker inicia el treballador, gestionant la seva interacció amb el fil principal.

L'ordre seqtk s'executa amb Worker al fitxer muntat. Un cop finalitzada l'execució, el treballador produeix un resultat en forma de Promesa. Quan el fil principal rep un missatge, el resultat s'utilitza per actualitzar els gràfics. I així successivament en diverses iteracions.

Què passa amb el rendiment de WebAssembly?

Per avaluar el canvi en el rendiment, l'equip del projecte va utilitzar el paràmetre d'operacions de lectura per segon. El temps que triga a construir gràfics interactius no es té en compte ja que ambdues implementacions utilitzen JavaScript.

Quan s'utilitzava la solució immediata, l'augment de rendiment va ser nou vegades.

Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

Aquest és un resultat excel·lent, però, segons resulta, també hi ha l'oportunitat d'optimitzar-lo. El fet és que seqtk no utilitza un gran nombre de resultats de l'anàlisi de control de qualitat, de manera que es poden suprimir. Si feu això, el resultat millora 13 vegades en comparació amb JS.

Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

Es va aconseguir simplement comentant les ordres printf().

Però això no és tot. El cas és que en aquesta fase, fastq.bio rep els resultats de l'anàlisi cridant diferents funcions C. Cadascuna d'elles calcula el seu propi conjunt de característiques, de manera que cada fragment del fitxer es llegeix dues vegades.

Per solucionar aquest problema, es va decidir combinar dues funcions en una sola. Com a resultat, la productivitat va augmentar 20 vegades.

Com vam accelerar una aplicació web 20 vegades mitjançant WebAssembly

Val la pena assenyalar que no sempre es pot aconseguir un resultat tan excepcional. En alguns casos, el rendiment baixarà, per la qual cosa val la pena avaluar cada cas.

Com a conclusió, podem dir que Wasm ofereix una oportunitat per millorar el rendiment de l'aplicació, però cal utilitzar-lo amb prudència.

Skillbox recomana:

Font: www.habr.com

Afegeix comentari