Webassemblyマルチスレッド用crateを調べる: Rustが征く(7)
nightlyは当たり前
関連記事:
Rustが征くシリーズ過去記事
先に言っておくが、
ただ動かすだけでも難しい。
(nightlyビルドは当たり前、ビルドターゲット指定、クロスオリジン問題とかもある)
PHPやJavaScriptのエンジニアにとって、
生涯無縁の技術が マルチスレッド
複数のスレッドを立てて並列処理させる仕組みだ。
WebAssemblyでは可能になるとのことでずっと調査をしていた。
結論から言うとWebAssembly単独でマルチスレッドを実現するのは無理っぽい。
ブラウザのWebWorker APIを使用することになるのだが、
ちょっと微妙で実用性は疑問ではある。
とある方のスライドだが、
この図がすべてを物語っている。
2019年のスライドだけど、
令和3年9月現在も変わっていない。
この仕組みならJSで全部やればいいという話で、
よほどAIやマイニング、2D,3D物理演算などの計算速度が必要なものを、
巧く実装しない限りメリットを得られないことがわかる。
(JS <-> WASM間のデータやりとりやファイルロードなんかも普通に遅いからね)
('ω') まぁせっかく調べたから記事化しよ
crateを調べたところ、
WebWorkerをマスクする系のものが3つあった。
そのうち一つ一つ試すと思うが、
とりあえず今回はそれをリスト化してみよう。
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪
------------------- ↓ 本題はここから ↓-------------------
マルチスレッド関連では以下のモジュールがある。
wasm-bindgen-rayon
通常の繰り返し処理を並列処理するrayonをWebAssembly対応したもの。
Google謹製のライブラリだが、
今のところ以下のエラーがでて正常動作しない。
(動いてはいるっぽいけどなぁ)
エラー全文
wasm_rayon_bg.wasm:0xde45 Uncaught (in promise) RuntimeError: Atomics.wait cannot be called in this context
at wasm_rayon_bg.wasm:0xde45
at wasm_rayon_bg.wasm:0xe92e
at wasm_rayon_bg.wasm:0x9182
at wasm_rayon_bg.wasm:0xe6cf
at wasm_rayon_bg.wasm:0xb4da
at wasm_rayon_bg.wasm:0x9646
at wasm_rayon_bg.wasm:0xe62e
at wbg_rayon_PoolBuilder.build (wasm_rayon.js:139)
at startWorkers (workerHelpers.no-bundler.js:69)
at async main.mjs:5
(Googleは相変わらず仕事が雑だ)
コンパイル条件は
設定項目 | 設定値 |
---|---|
toolchain | nightly-2021-07-29 |
build.target | wasm32-unknown-unknown |
build.rustflags | ["-C", "target-feature=+atomics,+bulk-memory"] |
unstable.build-std | ["panic_abort", "std"] |
wasm-pack target | web |
wasm-mt
今のところ安定して使用できるマルチスレッド実行環境。
謎技術過ぎてよくわかってない。
ビルドターゲットがno-modulesなので取り回しに注意が必要
コンパイル条件は
設定項目 | 設定値 |
---|---|
toolchain | nightly-2021-07-28 |
build.target | wasm32-unknown-unknown |
wasm-pack target | no-modules |
wasm_thread
Rust標準のstd::threadを置換するだけでマルチスレッドが実現できることをコンセプトにしたモジュール
条件が細かすぎてちょっとよーわからん。
たぶんこうかな。
コンパイル条件は
設定項目 | 設定値 |
---|---|
toolchain | nightly-2021-07-29 |
build.target | wasm32-unknown-unknown |
build.rustflags | ["-C", "target-feature=+atomics,+bulk-memory"] |
unstable.build-std | ["panic_abort", "std"] |
wasm-pack target | no-modules |
------------------- ↓ 後書はここから ↓-------------------
また、webpackなどのバンドラーとも相性が悪い。
バンドラーは基本的にファイルを一つにするのだが、
Web Workerが呼び出すJSが単独で一枚必要になる。
WebPackでは以下のプラグインを使うといいらしい
wasm-futures-executor
新しいので調べ切れてないけど、
wasm-futures-executorというのが増えていた。
内容的にはwasm-bindgen-rayonやwasm_threadをリスペクトしていて、
ビルド条件も大体同じっぽい。
targetはwebなので扱いやすいかもだが、
workerファイルは別途生成するので、
バンドラーを使う場合は工夫が必要だ。
テスト的にビルドして上記2つと違いエラーはなかったので、
そのうち記事にするかもしれない。
Discussion