WASM + Rust + WebWorker 实现计算器(
Published on Fri Apr 08 2022 23:00:00 GMT+0000
WASM + Rust + WebWorker 实现高性能计算器
假设我们现在需要执行一个 CPU 负载很大的运算。为了不阻塞主线程,我们希望用 Web Worker 将其放到一个新的线程中进行运算,这样就可以避免阻塞主线程。
而为了提高这个运算的性能,我们希望用 Rust 编写的 WASM 程序来运算。
本文就将实现在 Web Worker 中调用 WASM 进行运算。
首先,我们来编写一段 Rust 代码,用于完成实际的计算。
1 2 3 4 5 6 7 8 9 10 11
| extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen] extern "C" {}
#[wasm_bindgen] pub fn wasm_add(a: i32, b: i32) -> i32 { a + b }
|
然后,将其编译为 WASM ,具体的方法参见我的上一篇博文。
接下来,我们需要创建一个网页,用于测试我们的函数。
1 2 3 4 5 6 7 8 9 10
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>TestWoker</title> </head> <body> <script type="module" src="script.js"></script> </body> </html>
|
在 script.js
里面,我们要创建一个 Web Worker。
1 2 3 4 5 6 7 8 9 10 11 12 13
| if (window.Worker) { const myWorker = new Worker('./worker.js', {type: 'module'}); myWorker.postMessage([1, 2]); myWorker.postMessage([3, 4]); setTimeout(() => { myWorker.postMessage([7, 8]) }, 1000); myWorker.onmessage = (m) => { const data = m.data; console.log('data from wasm: ' + data); } }
|
然后在 Web Worker 里面,导入并编译 WASM 程序,在收到消息的时候执行计算,并将结果返回给主线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import init from './pkg/hello_wasm.js'; import {wasm_add} from './pkg/hello_wasm.js';
let isWasmInit = false;
init().then(() => isWasmInit = true);
onmessage = function (m) { const data = m.data; if (isWasmInit) { console.log('Wasm init before message'); run(); } else { console.log('Wasm not init before message'); init().then(() => { run(); isWasmInit = true; } ); }
function run() { const res = wasm_add(data[0], data[1]); postMessage(res); } }
|
这样,我们就实现了一个不阻塞主线程的,高性能的加法。(好像没有什么卵用
但是想想看,如果这是一个加密或解密算法,或者音视频转码,是不是就很有必要了?