{"id":1279,"date":"2025-05-30T18:43:04","date_gmt":"2025-05-30T18:43:04","guid":{"rendered":"https:\/\/cloudlab.urv.cat\/catedracloud\/?p=1279"},"modified":"2025-05-30T18:44:10","modified_gmt":"2025-05-30T18:44:10","slug":"entendiendo-wasi-threads-paralelismo-eficiente-en-webassembly","status":"publish","type":"post","link":"https:\/\/cloudlab.urv.cat\/catedracloud\/2025\/05\/30\/entendiendo-wasi-threads-paralelismo-eficiente-en-webassembly\/","title":{"rendered":"Entendiendo WASI Threads: Paralelismo eficiente en WebAssembly"},"content":{"rendered":"\n<p>Introd<strong><em>Entendiendo WASI Threads: Paralelismo eficiente en WebAssembly<\/em><\/strong><\/p>\n\n\n\n<p>Siguiendo nuestra serie de art\u00edculos sobre WebAssembly (Wasm), hoy hablaremos de como traer paralelismo a WebAssembly. Con el crecimiento del ecosistema WebAssembly, cada vez son m\u00e1s las aplicaciones que buscan beneficiarse de su portabilidad, seguridad y rendimiento. Sin embargo, una limitaci\u00f3n importante hasta la fecha ha sido la falta de soporte para ejecuci\u00f3n de c\u00f3digo multihilo. Ah\u00ed es donde entra<mark class=\"has-inline-color has-primary-color\"> WASI Threads<\/mark>, una propuesta clave para llevar el paralelismo nativo al entorno Wasm de forma segura y eficiente.<\/p>\n\n\n\n<p>En esta entrada exploraremos qu\u00e9 es <mark class=\"has-inline-color has-primary-color\">WASI Threads<\/mark>, c\u00f3mo funciona y por qu\u00e9 es un paso fundamental para el futuro de Wasm.ucci\u00f3n<\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-6d0a7b0b\"><h5 class=\"uagb-heading-text\"><strong><em>Primero de todo, un recordatorio sobre WASI<\/em><\/strong><\/h5><\/div>\n\n\n\n<p><strong>WASI <\/strong>(<strong>WebAssembly System Interface<\/strong>) es una interfaz est\u00e1ndar que permite que los m\u00f3dulos Wasm interact\u00faen con el sistema operativo (archivos, red, reloj, etc.) de forma segura y portable, sin acceso directo al hardware o a llamadas nativas como <span style=\"font-family: monospace;color: #333\">open()<\/span> o <span style=\"font-family: monospace;color: #333\">fork()<\/span>, que dependen del sistema operativo subyacente.<\/p>\n\n\n\n<p>En el caso que nos ocupa, el modelo de ejecuci\u00f3n de Wasm ha sido estrictamente monohilo, siguiendo el comportamiento en los navegadores, lo que limitaba su uso en tareas computacionalmente intensivas, como procesamiento de im\u00e1genes, bases de datos, simulaciones f\u00edsicas o aprendizaje autom\u00e1tico.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-bbd92e97\"><h5 class=\"uagb-heading-text\"><strong><em>WASI Threads: El siguiente paso<\/em><\/strong><\/h5><\/div>\n\n\n\n<p><mark class=\"has-inline-color has-primary-color\">WASI Threads<\/mark> es una extensi\u00f3n propuesta al est\u00e1ndar WASI que habilita el uso de hilos nativos en WebAssembly. Su objetivo es permitir que una aplicaci\u00f3n Wasm aproveche m\u00faltiples n\u00facleos del CPU, usando una API basada en pthreads (<span style=\"font-family: monospace;color: #333\">std::thread<\/span> en C++\/Rust), pero en un entorno controlado y seguro. Con WASI Threads es posible ejecutar de forma paralela el siguiente programa para sumar 1000 n\u00fameros:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;pthread.h&gt;\n\n#define NUM_THREADS 4\n#define ARRAY_SIZE 1000\n\nint array&#091;ARRAY_SIZE];\nlong partial_sums&#091;NUM_THREADS];\n\ntypedef struct {\n    int thread_id;\n    int start;\n    int end;\n} thread_args_t;\n\nvoid* compute_sum(void* arg) {\n    thread_args_t* args = (thread_args_t*)arg;\n    long sum = 0;\n    for (int i = args-&gt;start; i &lt; args-&gt;end; ++i) {\n        sum += array&#091;i];\n    }\n    partial_sums&#091;args-&gt;thread_id] = sum;\n    return NULL;\n}\n\nint main() {\n    \/\/ Inicializa el array\n    for (int i = 0; i &lt; ARRAY_SIZE; ++i) {\n        array&#091;i] = 1;  \/\/ Valor fijo para f\u00e1cil verificaci\u00f3n\n    }\n\n    pthread_t threads&#091;NUM_THREADS];\n    thread_args_t args&#091;NUM_THREADS];\n    int chunk_size = ARRAY_SIZE \/ NUM_THREADS;\n\n    \/\/ Crear hilos\n    for (int i = 0; i &lt; NUM_THREADS; ++i) {\n        args&#091;i].thread_id = i;\n        args&#091;i].start = i * chunk_size;\n        args&#091;i].end = (i == NUM_THREADS - 1) ? ARRAY_SIZE : (i + 1) * chunk_size;\n        pthread_create(&amp;threads&#091;i], NULL, compute_sum, &amp;args&#091;i]);\n    }\n\n    \/\/ Esperar a que los hilos terminen\n    for (int i = 0; i &lt; NUM_THREADS; ++i) {\n        pthread_join(threads&#091;i], NULL);\n    }\n\n    \/\/ Sumar los resultados parciales\n    long total = 0;\n    for (int i = 0; i &lt; NUM_THREADS; ++i) {\n        total += partial_sums&#091;i];\n    }\n\n    printf(\"Suma total: %ld\\n\", total);\n    return 0;\n}<\/code><\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-8abc3453\"><h5 class=\"uagb-heading-text\"><strong><em>\u00bfC\u00f3mo funciona?<\/em><\/strong><\/h5><\/div>\n\n\n\n<p><mark class=\"has-inline-color has-primary-color\">WASI Threads<\/mark> se basa en:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Memoria compartida<\/strong>: Se habilita la memoria compartida entre instancias Wasm que se ejecutan de forma concurrente en distintos hilos en el espacio de usuario.<\/li>\n\n\n\n<li><strong>Hilos en el entorno anfitri\u00f3n<\/strong>: Cada hilo de Wasm es gestionado por el sistema operativo subyacente mediante hilos nativos. T\u00edpicamente, por cada hilo de Wasm, la m\u00e1quina virtual crea un hilo nativo, manteniendo una correspondencia 1:1 entre hilos Wasm e hilos del sistema.<\/li>\n\n\n\n<li><strong>Funci\u00f3n status wasi_thread_spawn(thread_start_arg* start_arg)<\/strong>: Esta funci\u00f3n es llamada desde el m\u00f3dulo Wasm y sirve para solicitar a la m\u00e1quina virtual la creaci\u00f3n de un nuevo hilo de ejecuci\u00f3n Wasm.<\/li>\n\n\n\n<li><strong>Requisitos actuales<\/strong>: Esta funcionalidad requiere habilitar ciertas opciones experimentales tanto al compilar como al ejecutar, y solo est\u00e1 disponible en m\u00e1quinas virtuales que ya soportan <mark class=\"has-inline-color has-primary-color\">WASI Threads<\/mark>, como Wasmtime, Wasmer o WAMR. Por ejemplo, en Wasmtime esto requiere usar el flag \u2013enable-threads: <code>$wasmtime run --enable-threads parallel.wasm<\/code><\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-0cbde790\"><h5 class=\"uagb-heading-text\"><strong><em>Retos de seguridad y aislamiento<\/em><\/strong><\/h5><\/div>\n\n\n\n<p>Uno de los desaf\u00edos clave en la incorporaci\u00f3n de hilos a Wasm es mantener el aislamiento entre m\u00f3dulos. El uso de memoria compartida introduce riesgos cl\u00e1sicos como condiciones de carrera (data races) o bloqueos mutuos (deadlocks). Por eso, WASI Threads incorpora mecanismos para garantizar<strong><em>:<\/em><\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Control de acceso a memoria compartida, que se garantiza mediante el uso de instrucciones de acceso at\u00f3mico como <code>i32.atomic.rmw.cmpxchg<\/code>.<\/li>\n\n\n\n<li>Aislamiento entre instancias en sistemas multiusuario.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-38d55a7f\"><h5 class=\"uagb-heading-text\"><strong><em>\u00bfPor qu\u00e9 importa WASI Threads?<\/em><\/strong><\/h5><\/div>\n\n\n\n<p>Con el soporte multihilo, Wasm se convierte en una opci\u00f3n viable para:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Servidores edge multiusuario<\/li>\n\n\n\n<li>Procesamiento en paralelo (ML, multimedia)<\/li>\n\n\n\n<li>Portabilidad de librer\u00edas multihilo de C\/C++\/Rust<\/li>\n\n\n\n<li>Aplicaciones cient\u00edficas y de alto rendimiento (HPC)<\/li>\n<\/ul>\n\n\n\n<p>En un reciente art\u00edculo publicado en la prestigiosa conferencia IEEE CCGrid\u201925, titulado <em>&#8216;Let It Unthread: The Good, The Bad and The Ugly within WebAssembly Portable Multithreading&#8217;<\/em>, se demuestra que Wasmtime puede alcanzar un rendimiento cercano al nativo (glibc) en aplicaciones reales como <em>blackscholes<\/em>, <em>fluidanimate<\/em> o <em>swaptions<\/em>.<\/p>\n\n\n\n<div class=\"wp-block-uagb-image uagb-block-3b87fbe4 wp-block-uagb-image--layout-default wp-block-uagb-image--effect-static wp-block-uagb-image--align-none\"><figure class=\"wp-block-uagb-image__figure\"><img decoding=\"async\" src=\"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/parsec.png\" alt=\"\" class=\"uag-image-1283\" width=\"875\" height=\"657\" title=\"parsec\" loading=\"lazy\" role=\"img\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-377a1953\"><h5 class=\"uagb-heading-text\">Conclusi\u00f3n<\/h5><\/div>\n\n\n\n<p><mark class=\"has-inline-color has-primary-color\">WASI Threads<\/mark> representa un hito en la evoluci\u00f3n de WebAssembly: un paso decisivo hacia la ejecuci\u00f3n eficiente y paralela en un entorno portable, seguro y moderno. Aunque a\u00fan est\u00e1 en fase experimental, su desarrollo avanza con rapidez, y todo indica que ser\u00e1 una pieza clave del futuro de la computaci\u00f3n basada en WebAssembly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>IntrodEntendiendo WASI Threads: Paralelismo eficiente en WebAssembly Siguiendo nuestra serie de art\u00edculos sobre WebAssembly (Wasm), hoy hablaremos de como traer paralelismo a WebAssembly. Con el crecimiento del ecosistema WebAssembly, cada vez son m\u00e1s las aplicaciones que buscan beneficiarse de su portabilidad, seguridad y rendimiento. Sin embargo, una limitaci\u00f3n importante hasta la fecha ha sido la [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":1282,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","_swt_meta_header_display":false,"_swt_meta_footer_display":false,"_swt_meta_site_title_display":false,"_swt_meta_sticky_header":false,"_swt_meta_transparent_header":false,"footnotes":""},"categories":[113,33],"tags":[21,101],"class_list":["post-1279","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-computing","category-webassembly","tag-cloud-computing","tag-webassembly"],"jetpack_featured_media_url":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme.png","uagb_featured_image_src":{"full":["https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme.png",1024,1024,false],"thumbnail":["https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme-150x150.png",150,150,true],"medium":["https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme-300x300.png",300,300,true],"medium_large":["https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme-768x768.png",768,768,true],"large":["https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme.png",1024,1024,false],"1536x1536":["https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme.png",1024,1024,false],"2048x2048":["https:\/\/cloudlab.urv.cat\/catedracloud\/wp-content\/uploads\/2025\/05\/WASI_Threads_scheme.png",1024,1024,false]},"uagb_author_info":{"display_name":"Marc S\u00e1nchez Artigas","author_link":"https:\/\/cloudlab.urv.cat\/catedracloud\/author\/msanchez\/"},"uagb_comment_info":5,"uagb_excerpt":"IntrodEntendiendo WASI Threads: Paralelismo eficiente en WebAssembly Siguiendo nuestra serie de art\u00edculos sobre WebAssembly (Wasm), hoy hablaremos de como traer paralelismo a WebAssembly. Con el crecimiento del ecosistema WebAssembly, cada vez son m\u00e1s las aplicaciones que buscan beneficiarse de su portabilidad, seguridad y rendimiento. Sin embargo, una limitaci\u00f3n importante hasta la fecha ha sido la&hellip;","_links":{"self":[{"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/posts\/1279","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/comments?post=1279"}],"version-history":[{"count":2,"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/posts\/1279\/revisions"}],"predecessor-version":[{"id":1284,"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/posts\/1279\/revisions\/1284"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/media\/1282"}],"wp:attachment":[{"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/media?parent=1279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/categories?post=1279"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudlab.urv.cat\/catedracloud\/wp-json\/wp\/v2\/tags?post=1279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}