ネイティブマルチスレッドJavaScriptとWASMの性能比較

作者: リン・ハーン発明者の量化, 日付: 2023-02-23 17:35:24
タグ:複数の糸

開発者らは,JavaScriptをネイティブの低層から真正な意味のあるマルチスレッドをサポートするために量化試み,そしてWASM機能を追加した.下記は,最新ホストをダウンロードするDEMOで,体験を味わうことができます. この機能は,JavaScript以外のWorker機能で,複数のスレッド内の相互通信またはメインスレッドとの通信を使用できます.

C言語の翻訳は,このウェブサイトからテストを作成することができます: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 でヘックス文字列に変換する

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

代入コードの変数の後ろの内容は

_スレッド (関数,引数...)

スレッドを作成し,スレッド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指等待主线程的消息

_threadJoin (ジョイン) タイムアウト)

待ちスレッド終了 指定timeout (ミリ秒) 指定待ちスレッド終了まで待ち続け,機能が返した値を含む構造を成功裏に返却し,リソースを回収します.構造は以下のとおりです.

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

超時回帰が未定義になる場合

_threadTermine (終了) _ (終了)

強制的にスレッドを終了し,リソースをリサイクルします (__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) ファイル: ファイル: ファイル: ファイル: ファイル: ファイル: ファイル: ファイル: ファイル: ファイル:

発明者の量化最新のホストにアップグレード