Hay subprocesos de WebAssembly listos para probar en Chrome 70

La compatibilidad con subprocesos de WebAssembly se envió en Chrome 70 en una prueba de origen.

Alex Danilo

WebAssembly (Wasm) permite la compilación de código escrito en C++ y otras lenguajes de programación en la Web. Una función muy útil de las aplicaciones nativas es la capacidad de usar subprocesos, una primitiva para el procesamiento en paralelo. Más C y los desarrolladores de C++ ya conocerían pthreads, que es un API estandarizada para la administración de subprocesos en una aplicación.

El WebAssembly Community Group ha estado trabajando para llevar subprocesos a la Web y habilitar aplicaciones multiproceso reales. Como parte de este esfuerzo, V8 implementó la compatibilidad necesaria para los subprocesos en el motor de WebAssembly, disponible a través de una prueba de origen. Las pruebas de origen permiten a los desarrolladores experimentar con nuevas funciones web antes de que se estandaricen por completo. Esto nos permite recopilar comentarios reales de desarrolladores intrépidos, lo que es fundamental para validar y mejorar las funciones nuevas.

La versión de Chrome 70 es compatible con los subprocesos de WebAssembly. a los desarrolladores interesados a usarlos y enviarnos sus comentarios.

¿Hilos? ¿Qué sucede con los trabajadores?

Los navegadores admiten el paralelismo con Web Workers desde 2012 en Chrome 4. en Es normal escuchar términos como "en el subproceso principal" etc. Sin embargo, Web Los trabajadores no comparten datos mutables entre ellos, sino que confían en y el paso de mensajes para la comunicación. De hecho, Chrome asigna un nuevo motor V8 para cada uno de ellos (llamados aislamientos). Los aislamientos no comparten código compilado ni objetos JavaScript y, por lo tanto, no pueden compartir datos mutables, como pthreads.

Por otro lado, los subprocesos de WebAssembly son subprocesos que pueden compartir el mismo Wasm memoria. El almacenamiento subyacente de la memoria compartida se logra con un SharedArrayBuffer, una primitiva de JavaScript que permite compartir el contenido de un solo ArrayBuffer de forma simultánea entre los trabajadores. Cada subproceso de WebAssembly se ejecuta en un Web Worker, pero su memoria compartida de Wasm les permite trabajar como lo hacen en aplicaciones y plataformas de Google Cloud. Esto significa que las aplicaciones que usan subprocesos de Wasm responsable de administrar el acceso a la memoria compartida, como en cualquier aplicación de múltiples subprocesos. Existen muchas bibliotecas de código existentes escritas en C o C++ que usan pthreads, y que se pueden compilar en Wasm y ejecutar en modo de subprocesos verdadero, lo que permite que más núcleos trabajen en los mismos datos de forma simultánea.

Un ejemplo sencillo

Este es un ejemplo de un programa "C" simple que usa subprocesos.

#include <pthread.h>
#include <stdio.h>

// Calculate Fibonacci numbers shared function
int fibonacci(int iterations) {
    int     val = 1;
    int     last = 0;

    if (iterations == 0) {
        return 0;
    }
    for (int i = 1; i < iterations; i++) {
        int     seq;

        seq = val + last;
        last = val;
        val = seq;
    }
    return val;
}
// Start function for the background thread
void *bg_func(void *arg) {
    int     *iter = (void *)arg;

    *iter = fibonacci(*iter);
    return arg;
}
// Foreground thread and main entry point
int main(int argc, char *argv[]) {
    int         fg_val = 54;
    int         bg_val = 42;
    pthread_t   bg_thread;

    // Create the background thread
    if (pthread_create(&bg_thread, NULL, bg_func, &bg_val)) {
        perror("Thread create failed");
        return 1;
    }
    // Calculate on the foreground thread
    fg_val = fibonacci(fg_val);
    // Wait for background thread to finish
    if (pthread_join(bg_thread, NULL)) {
        perror("Thread join failed");
        return 2;
    }
    // Show the result from background and foreground threads
    printf("Fib(42) is %d, Fib(6 * 9) is %d\n", bg_val, fg_val);

    return 0;
}

Ese código comienza con la función main(), que declara 2. variables fg_val y bg_val También hay una función llamada fibonacci(), a la que llamarán ambos subprocesos en este ejemplo. La función main() crea un subproceso en segundo plano con pthread_create() cuya tarea es calcular el valor de la secuencia de números de Fibonacci correspondiente a el valor de la variable bg_val Mientras tanto, el Función main() que se ejecuta en el subproceso en primer plano lo calcula para la variable fg_val. Una vez que se complete la ejecución del subproceso en segundo plano, se imprimirán los resultados.

Cómo compilar para admitir subprocesos

Primero, debes tener el SDK de emscripten instalada, preferentemente la versión 1.38.11 o posterior. Para compilar nuestro código de ejemplo con subprocesos habilitados para ejecutarse en el navegador, debemos pasar un par de marcas adicionales al compilador emscripten emcc. Nuestro la línea de comandos se ve de la siguiente manera:

emcc -O2 -s USE_PTHREADS=1 -s PTHREAD_POOL_SIZE=2 -o test.js test.c

El argumento de línea de comandos "-s USE_PTHREADS=1" activa la compatibilidad con subprocesos para el módulo WebAssembly compilado, y el argumento "-s PTHREAD_POOL_SIZE=2" le indica al compilador que genere un grupo de dos (2) subprocesos.

Cuando se ejecute el programa, cargará el módulo WebAssembly, creará un trabajador web para cada uno de los subprocesos del grupo de subprocesos, compartirá el módulo con cada uno de los trabajadores, en este caso son 2, y se usarán cada vez que se realice una llamada a pthread_create(). Cada trabajador crea una instancia Módulo de Wasm con la misma memoria, lo que les permite cooperar. Los cambios más recientes de V8 en la versión 7.0 comparten el código nativo compilado de los módulos Wasm que se pasan entre los trabajadores, lo que permite que incluso aplicaciones muy grandes se escalen a muchos trabajadores. Ten en cuenta que tiene sentido asegurarte de que el tamaño del conjunto de subprocesos sea igual al la cantidad máxima de subprocesos que necesita la aplicación o puede fallar la creación de subprocesos. Al mismo tiempo, si el conjunto de subprocesos es muy grande, a los trabajadores web innecesarios que no harán nada más que usar memoria.

Cómo probarlo

La forma más rápida de probar nuestro módulo de WebAssembly es activar el admiten subprocesos experimentales de WebAssembly a partir de Chrome 70. Navega a la URL about://flags en tu navegador, como se muestra a continuación:

Página de funciones experimentales de Chrome

A continuación, busca el parámetro de configuración experimental de subprocesos de WebAssembly, que se ve de la siguiente manera:

Configuración de subprocesos de WebAssembly

Cambia la configuración a Habilitado como se muestra a continuación y, luego, reinicia el navegador.

Configuración de subprocesos de WebAssembly habilitada

Una vez que se reinicie el navegador, podemos intentar cargar el WebAssembly del subproceso. con una página HTML mínima que incluya únicamente este contenido:

<!DOCTYPE html>
<html>
  <title>Threads test</title>
  <body>
    <script src="test.js"></script>
  </body>
</html>

Para probar esta página, deberás ejecutar algún tipo de servidor web y cargarlo desde tu navegador. Eso hará que el módulo WebAssembly se cargue y se ejecute. Si abres DevTools, se mostrará el resultado de la ejecución y deberías ver algo como la siguiente imagen de salida en la consola:

Resultado de la consola del programa de Fibonacci

Nuestro programa de WebAssembly con subprocesos se ejecutó correctamente. Te recomendamos que pruebes tu propia aplicación de subprocesos con los pasos descritos anteriormente.

Pruebas en el campo con una prueba de origen

Puedes probar las conversaciones activando marcas experimentales en el navegador. de desarrollo, pero si deseas probar tu aplicación en la campo, puedes hacerlo con lo que se conoce como prueba de origen.

Las pruebas de origen te permiten probar funciones experimentales con tus usuarios mediante la obtención un token de prueba que esté vinculado a tu dominio. Luego, puedes implementar tu app y esperar que funcione en un navegador que admita la función que estás probando (en este caso, Chrome 70 en adelante). Para obtener tu propio token y ejecutar una prueba de origen, haz lo siguiente: usar la aplicación aquí.

Alojamos nuestro ejemplo simple anterior con un token de prueba de origen para que puedas probarlo por tu cuenta sin necesidad de compilar nada.

Si quieres ver lo que 4 subprocesos que se ejecutan en paralelo pueden hacer por el arte ASCII, entonces debes mirar esta demostración.

Envíanos tus comentarios

Los subprocesos de WebAssembly son una primitiva nueva muy útil para portar aplicaciones a la Web. Ahora es posible ejecutar aplicaciones C y C++, y Bibliotecas que requieren compatibilidad con pthreads en el entorno de WebAssembly

Esperamos recibir comentarios de los desarrolladores que prueban esta función, ya que nos ayudará informar el proceso de estandarización y validar su utilidad. La mejor manera de enviar comentarios es informar problemas o participar en el proceso de estandarización en el grupo comunitario de WebAssembly.