Comparación de las prestaciones de JavaScript nativo con WASM

El autor:El inventor de la cuantificación, Fecha: 2023-02-23 17:35:24
Las etiquetas:Múltiples hilos

Los inventores intentan cuantificar desde el nivel inferior nativo para que JavaScript admita múltiples hilos verdaderamente significativos, e incluye la función WASM. A continuación hay una demostración para que los usuarios puedan descargar las últimas versiones. Esta funcionalidad es una función de Worker, que no es JavaScript, que se puede usar para comunicarse entre sí o con el hilo principal dentro de varios hilos.

La traducción del lenguaje C a wasm se puede generar a partir de este sitio:https://wasdk.github.io/WasmFiddle/

El código del lenguaje C compilado como wasm es el siguiente:

int fib(int f) {
  if (f < 2) return f;
  return fib(f - 1) + fib(f - 2);
}

Después de compilarlo, descargar el archivo wasm y luego convertirlo en una cadena hex en Python

python -c "print('data:hex,'+bytes.hex(open('program.wasm','rb').read()))"

El contenido detrás de las variables en el código de reemplazo

__Thread ((función, argumentos...)

Crear un hilo y devolver el tid del hilo, la función de la función principal del hilo aceptado debe completar todo el código de la función dentro de la función del hilo, no admite referencias a otras funciones de cierre, puede llamar a todas las API de la plataforma dentro del hilo, pero no puede llamar a otras funciones personalizadas por el usuario

Un ejemplo sencillo:

let tid = __Thread(function(x, y) {
    return x + y
}, 1, 2)
Log(__threadJoin(tid))

Ejemplos de peticiones de múltiples hilos:

function main() {
    let threads = [
        "https://www.baidu.com",
        "https://www.163.com"
    ].map(function(url) {
        return __Thread(function(url) {
            Log("GET", url)
            return HttpQuery(url)
        }, url)
    })
    threads.forEach(function(tid) {
        Log(__threadJoin(tid))
    })
}

Variables de almacenamiento local del hilo

Apoya la variable de almacenamiento local de los hilos para compartir fácilmente los datos que no están en los hilos.__threadJoinEsperar para salir con éxito o__threadTerminateFunciona en caso de terminación

__threadGetData(tid, key)
__threadSetData(tid, key, value)

tid es 0 para indicar el hilo actual, el valor no especificado para indicar la clave de eliminación, el soporte de variables de acceso compartido entre hilos, el valor debe ser una variable seriable

Comunicación por hilos

__threadPostMessage(tid, msg) // 向指定线程发送消息, tid为0是向主线程即当前主函数发送, 在线程内部调用指向主线程回复消息, 该消息可以被EventLoop捕获
__threadPeekMessage(tid, timeout) // 从指定线程接收消息, 如果不指定timeout(毫秒)就一直等待, tid为0指等待主线程的消息

_threadJoin ((tido, tiempo muerto)

Para especificar un tiempo de espera no puede ser especificado, sino que se espera hasta el final del hilo, regresando con éxito una estructura que contiene la función de valor de retorno y recuperando los recursos, la estructura es la siguiente:

{
    id: tid, // 线程id
    elapsed: 1111, // 线程的运行时间(纳秒)
    terminated: false, // 线程是否被强制结束 
    ret: 123, // 线程函数的返回值
}

Si el tiempo de espera regresa indefinido

__threadTerminate ((tiempo)

Forzar la terminación del hilo y recuperar los recursos (no se puede usar __threadJoin más hasta el final)

Cuidado.

La función __Thread no soporta variables de referencia fuera de la función (para operar en un entorno aislado), y la referencia a variables externas fracasará en la compilación.


function main() {
    let cycle = 100
    let input = 30
    let threads = [
        __Thread(function(cycle, input) {
            function fib(f) {
                if (f < 2) return f
                return fib(f - 1) + fib(f - 2)
            }
            let ret = 0
            for (let i = 0; i < cycle; i++) {
                ret = fib(input);
                Log("javascript progress: ", i)
            }
            return 'javascript fib: ' + ret
        }, cycle, input),
        
        __Thread(function(cycle, input) {
            let data = 'data:hex,0061736d010000000186808080000160017f017f0382808080000100048480808000017000000583808080000100010681808080000007908080800002066d656d6f727902000366696200000aa480808000019e80808000000240200041024e0d0020000f0b2000417f6a10002000417e6a10006a0b'
            let m = wasm.parseModule(data)

            let instance = wasm.buildInstance(m, {
                stack_size: 65 * 1024 * 1024,
            })

            let ret = 0
            for (let i = 0; i < cycle; i++) {
                ret = instance.callFunction('fib', input)
                Log("wasm progress: ", i)
            }

            return 'wasm fib: ' + ret
        }, cycle, input)
    ]

    threads.forEach(function(tid) {
        let info = __threadJoin(tid)
        Log('#'+tid, info.ret, 'elapsed:', info.elapsed / 1e6, "#ff0000")
    })
}

Relacionados

Más.

Cuchillo de huesoCorrección: Error ReferenceError: '__Thread' no está definido en el eje principal (FILE:5)

El inventor de la cuantificaciónActualizar a la última administración