Сравнение производительности JavaScript с WASM

Автор:Изобретатель количественный, Дата: 23 февраля 2023 года 17:35:24
Тэги:Многопроводный

Изобретатели количественно пытаются сделать JavaScript поддерживающим действительно значимые многоуровневые потоки с его собственного нижнего слоя и включить функции WASM. Ниже представлена демонстрация, которую можно скачать для новейших хостеров. Функция Worker, не являющаяся JavaScript, может использоваться для общения между несколькими потоками или для общения с основными потоками.

С помощью этого веб-сайта вы можете создать тесты на язык C:https://wasdk.github.io/WasmFiddle/

Код языка C, компилируемый как wasm, выглядит так:

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

После компиляции загрузить файл wasm и преобразовать его в шестеренку с помощью python

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

Замена кода на переменные может быть сделана с помощью

__Thread ((функция, аргументы...)

Создание потока и возвращение потока tid, функции принимаемых субъективных функций должны выполнять весь функциональный код внутри потока, не поддерживают ссылки на другие закрытые функции, можно вызвать все API платформы внутри потока, но нельзя вызвать другие пользовательские функции

Простые примеры:

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

Примеры запросов с несколькими потоками:

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))
    })
}

Местное хранилище переменных

Поддержка локального хранения вещей для потоков, чтобы облегчить обмен данными, которые не хранятся в потоках.__threadJoinПодождите успешного выхода или__threadTerminateДействие при прекращении

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

tid 0 обозначает текущую нить, value unspecified обозначает delete key, поддерживает взаимный доступ к общим переменным между нитями, значение должно быть серийным.

Связь по проводам

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

_threadJoin (присоединиться)

Определение timeout (миллисекунды) для определения времени ожидания не может быть указано, т.е. ждать до конца потока, успешно возвращать структуру, содержащую возвращаемое значение функции, и восстанавливать ресурсы, структура:

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

Если отсрочка возвращает undefined

__threadTerminate ((tid))

Принудительное завершение потока и восстановление ресурсов ((невозможно использовать__threadJoin до завершения)

Осторожно.

Функция __Thread не поддерживает ссылки на нефункциональные переменные (для работы в изолированной среде), ссылки на внешние переменные будут компилироваться неудачно


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")
    })
}

Связанные

Больше

Костяные ножиУказание на выполнение: ошибка ReferenceError: '__Thread' is not defined at main (FILE:5)

Изобретатель количественныйОбновление на новейший хост