네이티브 멀티 스레드 자바스크립트와 WASM 성능 비교

저자:발명가 양자화, 날짜: 2023-02-23 17:35:24
태그:다중 유선

개발자는 자바스크립트를 본래의 하위층에서 진정한 의미의 멀티 스레드를 지원하도록 시도하고 WASM 기능을 추가했습니다. 아래는 최신 호스트를 다운로드 할 수있는 데모입니다. 이 기능은 자바스크립트 이외의 워커 기능으로 여러 스레드 내의 상호 통신 또는 메인 스레드와의 통신을 사용할 수 있습니다.

이 사이트에서 테스트를 생성할 수 있습니다:https://wasdk.github.io/WasmFiddle/

wasm로 컴파일된 C 언어 코드는 다음과 같습니다.

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

컴파일 후 wasm 파일을 다운로드 후 python로 hex 문자열로 변환

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는 지정하지 않고 삭제 키를 표시하고, 스레드 간의 상호 액세스 공유 변수를 지원합니다. 값은 순서화 가능한 변수가어야 합니다.

유선 통신

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

드레드 드레드, 타임아웃

유선 종료를 기다리는 시간 종료 (ms) 를 지정하여 유선 종료까지 계속 기다려야 함을 지정할 수 있습니다.

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

만약 시간이 지나면

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

발명가 양자화최신 호스트로 업그레이드