DOCUMENTACIÓN / COMPARACIÓN .NET/FFI Y WEBASSEMBLY
Comparación .NET/FFI y WebAssembly
Comparación material concluida; plataforma abierta
79 pares de corpus, 36000 muestras y fallos sintéticos comprobados. Ejecución local sin Actions. Se conservan los picos de latencia, el coste de memoria y los límites de autoridad.
Fecha: 6 de septiembre de 2026. Dictamen: COMPARACION_MATERIAL_REALIZADA_CON_LIMITES. No constituye selección definitiva de plataforma ni cierre del núcleo.
Resultado y valoración técnica
Las dos rutas son materialmente ejecutables desde .NET, mantienen la misma fuente Rust y conservan exactamente el estado y los bytes de salida de los 79 programas del corpus. La ruta nativa resulta más rápida y consume menos memoria residente. La variante WebAssembly ensayada contiene los dos fallos sintéticos y permite limitar instrucciones y memoria lineal. Ninguna protege al núcleo frente a un anfitrión comprometido con acceso a su instancia.
La diferencia de medianas centrales entre WASM y FFI es aproximadamente 8,6 µs para 510 bytes, 29,6 µs para 8 KiB y 194,3 µs para 64 KiB. El coste residente adicional de esta realización WASM ronda 47 MiB; inicializar su motor, compilar el módulo y completar la primera llamada lleva unos 198–249 ms. La inicialización nativa y primera llamada ocupa 1,87–2,52 ms. El arranque del proceso .NET queda fuera de estas últimas cifras.
Esta evidencia conserva WASM como candidata razonable de contención, con un coste material explícito. También acredita FFI como alternativa de menor coste para un anfitrión confiado. Si se desea contención comparable de fallos nativos, debe ensayarse su aislamiento de proceso y recuperación, incluyendo su coste; no está resuelto por P/Invoke. No se justifica declarar una ganadora universal ni sustituir la frontera de autoridad por cualquiera de estas tecnologías.
Se mantiene el núcleo ajeno a vigilancia operacional y decisiones de dominio. Una instancia persistente permite amortizar el arranque observado; esta observación no constituye todavía una política de ciclo de vida, recuperación o número de trabajadores. No se reintroduce una segunda compuerta de validación.
Qué se ha realizado
Un mismo anfitrión de ensayo .NET 10.0.400 carga dos adaptadores de ABI C mínima. Uno llama a una biblioteca Rust nativa; el otro utiliza la API C oficial de Wasmtime 48.0.1 para ejecutar el módulo WASM construido desde la misma copia exacta de sv_core. Ambas rutas incluyen copia de entrada, compilación, serialización, copia de salida y comprobación de respuesta.
La comparación utiliza procesos nuevos para cada grupo, con afinidad a dos CPU; cada instancia atiende un único llamante. Hay tres tamaños, tres repeticiones por ruta, 100 calentamientos y 2000 muestras útiles por grupo: 36000 muestras. Los tamaños de 8 y 64 KiB se obtienen con comentarios; no son programas semánticamente más complejos.
La actividad ejecutada es compilación y serialización de IR, por compile_svp y equivalence_json, perfil EN. No se ejerce R1, ejecución algebraica completa, contrato de dominio/agente, integración clínica, ensamblaje multifuente ni totalidad de la distribución ES/EN.
Paridad y controles
| Objeto | Observación |
|---|---|
| 12 programas positivos | Aceptados en ambas rutas, con igualdad exacta de IR. |
| 67 programas negativos | Rechazados en ambas rutas, con igualdad exacta de diagnóstico vigente. |
| Entrada vacía | El núcleo actual la acepta en ambas rutas; igualdad exacta de salida. Es un comportamiento observado, no una decisión normativa para la frontera final. |
| Sustitución por otro programa válido | Ambas rutas la aceptan; la compilación no acredita identidad ni autorización del original. |
| UTF-8 inválido y longitud excesiva | Rechazos de frontera diferenciados, sin convertirlos en U. |
| Salida con capacidad insuficiente | Rechazo, y una llamada posterior válida funciona. |
| Mutación de centinela por el anfitrión | Efectiva en ambas rutas. El PASS evidencia ausencia de protección frente a ese actor. |
| Combustible WASM insuficiente | Trap; una instancia nueva acepta el original. |
| Crecimiento WASM solicitado de 128 MiB | Rechazado con límite lineal de 64 MiB; la llamada posterior funciona. |
| Pánico sintético nativo | SIGABRT termina el anfitrión. |
| Pánico sintético WASM | Trap; el anfitrión permanece vivo. |
| Bucle sintético nativo | El supervisor termina el proceso propio con SIGKILL tras dos segundos desde READY. No es cancelación cooperativa de la FFI. |
| Bucle sintético WASM | El combustible agota la ejecución y devuelve trap; el anfitrión permanece vivo. |
Se verifican 8 controles nativos, 12 WASM y 4 observaciones de fallos sintéticos. Los 79 pares de corpus y la entrada vacía se cotejan además byte a byte. Un PASS del control defectuoso o de límite no certifica la seguridad de esa variante. No se atribuye un fallo sintético al núcleo canónico: las funciones de pánico, bucle y centinela pertenecen al adaptador experimental.
La representación Debug del error Rust se conserva exactamente en este corte. No es un contrato interversiones ya constituido. Las comprobaciones no sustituyen los oráculos y deudas del Lenguaje en sus sedes propias.
Latencia
Mediana central = mediana de las tres medianas. El rango de p99 recoge los tres percentiles por rango más próximo; no es intervalo de confianza ni garantía temporal.
| Entrada, bytes | Ruta | Mediana central, µs | Rango de p99, µs | Máximo observado, µs |
|---|---|---|---|---|
| 510 | Nativa / FFI | 9,134 | 21,673–22,223 | 163,295 |
| 510 | WASM con combustible | 17,776 | 36,034–46,359 | 245,488 |
| 8192 | Nativa / FFI | 38,878 | 60,420–106,790 | 632,247 |
| 8192 | WASM con combustible | 68,493 | 135,353–150,606 | 2121,599 |
| 65536 | Nativa / FFI | 263,074 | 339,679–474,351 | 1147,930 |
| 65536 | WASM con combustible | 457,405 | 793,038–1263,583 | 47744,474 |
Las colas de latencia impiden declarar una cota temporal: en las 6000 muestras WASM de 64 KiB hay 11 observaciones superiores a 5 ms, distribuidas entre dos repeticiones. Sus máximos son 47,744 ms y 35,222 ms. No se borran ni se atribuyen sin evidencia al planificador, a .NET o a Wasmtime. Los p99 y las medianas no sustituyen esos máximos.
La medición no acredita tiempo real, latencia máxima garantizada ni disponibilidad clínica. Tampoco permite comparar causalmente estos valores con las campañas 012 o 016: cambian el equipo, el transporte y el objeto ensayado.
CPU, memoria e inicialización
| Entrada, bytes | Ruta | CPU amortizada, µs/operación | RSS al finalizar, MiB | Inicialización + primera llamada, ms |
|---|---|---|---|---|
| 510 | Nativa / FFI | 10,347–10,565 | 30,20–30,27 | 1,87–2,03 |
| 510 | WASM con combustible | 19,585–20,082 | 76,83–77,45 | 197,99–201,84 |
| 8192 | Nativa / FFI | 40,986–42,853 | 30,25–30,51 | 1,87–1,98 |
| 8192 | WASM con combustible | 73,950–78,104 | 77,38–77,86 | 201,28–248,90 |
| 65536 | Nativa / FFI | 274,608–283,204 | 30,98–31,10 | 2,17–2,52 |
| 65536 | WASM con combustible | 487,441–617,707 | 76,98–79,24 | 204,20–224,80 |
CPU corresponde al proceso .NET y sus componentes nativos, usuario+sistema; no es recuento de ciclos ni energía. RSS es memoria residente observada, no pico simultáneo de un sistema completo. Se conservan también PeakWorkingSet64, PrivateMemorySize64, memoria virtual y recolecciones GC, sin confundirlas con memoria física exclusiva.
La memoria virtual observada es aproximadamente 77,97 GiB en la ruta nativa y 82,19 GiB en WASM. Son espacios de direcciones y reservas del proceso; no significan consumo físico de esa cantidad de RAM. La cifra pertinente de residencia está en la tabla. El límite WASM de 64 MiB se aplica a memoria lineal, no al conjunto de .NET, compilador JIT, motor y adaptadores. La memoria lineal observada en la carga es 2490368 bytes y permanece constante en las ventanas examinadas.
Observación de diez segundos y control de la instrumentación
La ruta nativa completa 34160 operaciones y la WASM 20933 durante aproximadamente diez segundos cada una, con una entrada fija de 64 KiB y un cliente secuencial. Estas cuentas no son capacidad máxima, saturación sostenida, tráfico abierto ni comparación concurrente de clientes.
Las ventanas registran un aumento RSS de 12,453 MiB en nativa y 12,449 MiB en WASM. Por ese hallazgo se añadió un control separado, sin cargar núcleo ni Wasmtime y sin efectuar llamadas al núcleo, que consulta las mismas propiedades de System.Diagnostics.Process durante diez segundos.
El control pasa de 25,172 a 37,184 MiB: incremento de 12,012 MiB. Por tanto, el aumento no es específico del núcleo ni de Wasmtime, y el observador/runtime contribuye materialmente a lo medido. El control no identifica toda la causa, no excluye fugas y no prueba estabilidad prolongada. No se restan mecánicamente esos 12 MiB a las otras cifras.
Identidades, entorno y reproducción
- Núcleo canónico:
230a205b08f4c54c9c8d9c1c7ad35b2f6ddbbfc4, preservado sin cambios. - Fuente de la tanda principal:
0189c4c2a38453826b450e7b201d8946055fd77c. - Fuente del control de observación:
73b452169ef1d848dadf0b5395abbb84341fb9ee. - Especificación:
comparacion-018/README.md, fijada antes de la tanda principal. La especificación del control declara el hallazgo que lo motivó. - Lecturas rectoras: AGENTS.md del núcleo, Pilares completos, acta de arquitectura 04/09 revisada 05/09, RETP-072/073 y registro 016.
- Linux x86-64 alojado; procesador expuesto AMD EPYC 9V74. Afinidad del ensayo a dos CPU; cuota de cgroup anfitrión de ocho CPU y límite de memoria de 20 GiB. El nombre comercial de 80 núcleos no es la dotación del ensayo.
- Rust/Cargo 1.98.0; .NET SDK 10.0.400; Wasmtime 48.0.1. Compilación Rust release, overflow-checks y panic=abort.
- Cada binario propio, entrada, salida y comando queda manifestado. La copia de fuente canónica y el corpus se cotejan por objetos Git, y los encabezados/biblioteca Wasmtime por SHA-256.
La tanda se construye y ejecuta localmente, sin GitHub Actions y sin solicitar API remotas en ejecución. Rust compila con --locked --offline; NuGet tiene fuentes vacías. La preparación descargó herramientas de proveedores oficiales con URL y huellas fijadas. La publicación de esta ficha continúa utilizando Pages; no se confunde autonomía de esta ejecución con autonomía integral del proyecto.
No hay paquetes NuGet ni nuevas dependencias de registro Cargo. Sí existen .NET, Wasmtime, compiladores y bibliotecas del sistema. La API C oficial evita añadir el adaptador NuGet de Wasmtime; el pequeño código de enlace pasa a ser una responsabilidad de mantenimiento del laboratorio. Wasmtime declara Apache-2.0 con excepción LLVM; no se altera la licencia de las fuentes SV.
Los pasos reproducibles se encuentran en comparacion-018/prepare.py y run.py. Para reproducir los números de la tanda, se utiliza su corte exacto o la copia de fuentes del ZIP, no una rama futura. La fuente del control es distinta y se conserva por separado.
Custodia y precisión del alcance
| Paquete privado | Bytes | SHA-256 |
|---|---|---|
| 018-comparacion-local.zip | 936909 | d8ba12907e0fabf779c5f75694e43e955053b34f24b681140d536571cfb574f0 |
| 018-control-observacion.zip | 50122 | d58fe8c86573b3cefaca9e923700c17ba94d3a7d7f4b2394d21be1d88c24ef73 |
El paquete principal contiene 421 entradas manifestadas más manifest.json. Se verifican CRC, pertenencia exacta, tamaños, todas las huellas, los 36000 valores crudos, los percentiles de 18 grupos y la igualdad de bytes del corpus. Los compiladores y el binario oficial de Wasmtime no se duplican en el ZIP: quedan identificados por sus archivos de dependencias y huellas. Esta custodia no es una copia externa independiente del proveedor.
Se conservan las incidencias de preparación: dos conflictos de nombres C# corregidos antes de medir, y la expectativa errónea de rechazo de entrada vacía corregida sin tocar el núcleo. No se ejecuta una regresión integral del prototipo de bus 0.2 porque no se modifica; su evidencia histórica permanece intacta.
Decisión que permite y obligaciones que permanecen
Se acredita el enlace técnico .NET→núcleo por las dos rutas en el perímetro declarado. WASM ofrece contención observada de los fallos sintéticos a cambio de memoria, inicialización y tiempo por llamada. FFI ofrece menor coste observado, con propagación del abort al anfitrión y dependencia del supervisor externo para detener el bucle. Es una comparación de implementaciones y configuraciones concretas.
Para cualquier promoción siguen pendientes: contrato versionado de frontera completo; identidad, autorización y repetición; enlace R1 con efectos; bus externo aislado; cancelación y recuperación constituidas; llamadas concurrentes, límites agregados y saturación; Windows/ARM y equipos físicos; corpus semánticamente diverso, perfiles y ensamblaje; presupuesto operacional y análisis de los picos de latencia.
La ausencia de WASI/importaciones y la memoria lineal acotada no convierten el núcleo en impenetrable. La separación de autoridad continúa siendo imprescindible tanto con FFI como con WASM. El núcleo no incorpora supervisión operacional ni decisiones IMM/CYB; el Playground funcional permanece preservado.
Fuentes técnicas externas
- Microsoft: P/Invoke y buenas prácticas de interoperabilidad.
- Bytecode Alliance: Wasmtime 48.0.1, API C, modelo de seguridad, memoria accesible por el anfitrión y política de versiones.
Las fuentes externas explican los mecanismos. Los resultados numéricos proceden exclusivamente de los paquetes de esta tanda.