html与c交互 webassembly,基于C的WebAssembly 和 Web Worker

纯C的比c++好编译和使用, 没有胶水的js, 以及简单的直接用exports就能拿到函数

这个是c的worker共享内存, 但是感觉效果也不是很好... wasm的多线程, 目前还没有表现比较好的例子

在浏览器或者node中直接运行

75d627c020b887754d8198fbea738696.png

WebAssembly.compile(

new Uint8Array(

`

00 61 73 6d 01 00 00 00 01 0c 02 60 02 7f 7f 01

7f 60 01 7f 01 7f 03 03 02 00 01 07 10 02 03 61

64 64 00 00 06 73 71 75 61 72 65 00 01 0a 13 02

08 00 20 00 20 01 6a 0f 0b 08 00 20 00 20 00 6c

0f 0b`

.trim()

.split(/[\s\r\n]+/g)

.map((str) => parseInt(str, 16))

)

).then((module) => {

const instance = new WebAssembly.Instance(module);

const { add, square } = instance.exports;

console.log("2 + 4 =", add(2, 4));

console.log("3^2 =", square(3));

console.log("(2 + 5)^2 =", square(add(2 + 5)));

});

math.c

int add(int x, int y)

{

return x + y;

}

int square(int x)

{

return x * x;

}

int fib(int n)

{

return n < 2 ? n : fib(n - 1) + fib(n - 2);

}

/*

emcc math.c -Os -s WASM=1 -s SIDE_MODULE=1 -o math.wasm

*/

node的使用

0e4b4320bceae07c0c5ea808d7f8df11.png

const url = "./cpp/math.wasm";

const fs = require("fs");

const buffer = fs.readFileSync(url);

WebAssembly.instantiate(buffer).then((wasm) => {

const instance = wasm.instance;

const add = instance.exports.add;

const square = instance.exports.square;

console.log("add", add(1, 2));

console.log("square", square(2));

});

web的使用, 和node的使用一样, 只是使用fetch来代替fs

730f48dd44a459d6e74e67b371d4bccf.png

Document

const url = "http://172.24.162.13:44593/cpp/math.wasm";

function loadWebAssembly(path) {

return fetch(path) // 加载文件

.then((res) => res.arrayBuffer()) // 转成 ArrayBuffer

.then(WebAssembly.instantiate) // 编译 + 实例化

.then((mod) => mod.instance); // 提取生成都模块

}

loadWebAssembly(url).then((instance) => {

const add = instance.exports.add;

const square = instance.exports.square;

console.log("add", add(1, 2));

console.log("square", square(2));

});

最简单的使用, 40项fib

每个计算用一个worker, 基本没啥提速的....

8604bcf5e498a0ac3600d2c68503382d.png

7e3e61c8c878c8ac28af3ee96863d506.png

会有大量请求

68e97d19e8d697b6f1689c7288a98a10.png

Document

const size = 40;

function workerPromise(n) {

const worker = new Worker("./fib-worker.js");

return new Promise((resolve) => {

worker.postMessage(n);

worker.onmessage = ({ data }) => {

// console.log(n, data);

resolve(data);

};

});

}

async function worker() {

const list = Array(size)

.fill()

.map((_, k) => k);

const st = +new Date();

const promiseList = list.map(workerPromise);

const resList = await Promise.all(promiseList);

const ed = +new Date();

console.log("wasm time:", ed - st);

console.log(list, resList);

}

worker();

async function test() {

const st = +new Date();

const url = "http://172.24.162.13:44593/cpp/math.wasm";

const fib = await fetch(url) // 加载文件

.then((res) => res.arrayBuffer()) // 转成 ArrayBuffer

.then(WebAssembly.instantiate) // 编译 + 实例化

.then((mod) => mod.instance.exports.fib);

const list = [];

for (let i = 0; i < size; i++) {

list.push(fib(i));

}

const ed = +new Date();

console.log("test time:", ed - st, list);

}

test();

const url = "http://172.24.162.13:44593/cpp/math.wasm";

function loadWebAssembly(path) {

return fetch(path) // 加载文件

.then((res) => res.arrayBuffer()) // 转成 ArrayBuffer

.then(WebAssembly.instantiate) // 编译 + 实例化

.then((mod) => mod.instance); // 提取生成都模块

}

self.onmessage = ({ data }) => {

// console.log("worker", data);

loadWebAssembly(url).then((instance) => {

const fib = instance.exports.fib;

self.postMessage(fib(data));

});

};

优化版, 一个worker, 感觉也没啥提升的...

虽然网络请求明显少了....

0e70688dd9d2209bf231193600952636.png

94aaecafe30c364d6d648c2e078a6433.png

Document

async function main() {

const url = "http://172.24.162.13:44593/cpp/math.wasm";

const buffer = await fetch(url) // 加载文件

.then((res) => res.arrayBuffer()); // 转成 ArrayBuffer

console.log("buffer", buffer);

const size = 40;

const begin = 0;

const worker = new Worker("./fib-worker4.js");

function workerPromise(n) {

return new Promise((resolve, reject) => {

const wasmBuffer = buffer.slice(0, buffer.byteLength);

worker.postMessage({ n, wasmBuffer });

const handle = ({ data }) => {

const { resN, fib } = data;

// console.log("onmessage", n, resN, fib);

if (resN === n) {

// console.log("resolve", n, resN, fib);

resolve(fib);

worker.removeEventListener("message", handle);

}

};

worker.addEventListener("message", handle);

});

}

async function workerTest() {

console.log("workerTest");

const st = +new Date();

const list = [];

for (let i = begin; i < size; i++) {

list.push(i);

}

const resList = await Promise.all(list.map(workerPromise));

const ed = +new Date();

console.log("wasm time:", ed - st);

console.log("res", resList);

}

workerTest();

async function test() {

const st = +new Date();

const wasm = await WebAssembly.instantiate(buffer);

const fib = wasm.instance.exports.fib; // 编译 + 实例化

const list = [];

for (let i = begin; i < size; i++) {

list.push(fib(i));

}

const ed = +new Date();

console.log("test time:", ed - st, list);

}

test();

}

main();

self.onmessage = async (msg) => {

// console.log("msg", msg);

const { n, wasmBuffer } = msg.data;

// console.log("worker wasmBuffer", n, wasmBuffer);

const wasm = await WebAssembly.instantiate(wasmBuffer);

const fib = wasm.instance.exports.fib;

const res = fib(n);

// console.log("worker res", n, res);

self.postMessage({ resN: n, fib: res });

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值