通过引用从 JS 传递数组以供 WASM 编辑?
Posted
技术标签:
【中文标题】通过引用从 JS 传递数组以供 WASM 编辑?【英文标题】:Pass arrays from JS by reference for WASM to edit? 【发布时间】:2020-01-15 19:06:25 【问题描述】:在 AssemblyScript 中传递和返回浮点数组的最佳方式是什么?
我可以传递一个数组形式 JS(通过引用)供 WASM 编辑吗?
export function nBodyForces(data: f64[], result: f64[]): void
以下是我现在所拥有的。忽略实现细节,它会返回 2000,然后将其增加到 8000ish。
返回一组新值的最佳方法是什么?
export function nBodyForces(data: f64[]): f64[]
// Each body has x,y,z,m passed in.
if (data.length % bodySize !== 0) return new Array<f64>(10);
const numBodies: i32 = data.length / bodySize;
// return a 3-force x,y,z vector for each body
let ret: f64[] = new Array<f64>(numBodies * forceSize);
/**
* Calculate the 3-vector each unique pair of bodies applies to each other.
*
* 0 1 2 3 4 5
* 0 x x x x x
* 1 x x x x
* 2 x x x
* 3 x x
* 4 x
* 5
*
* Sum those forces together into an array of 3-vector x,y,z forces
*/
// For all bodies:
for (let i: i32 = 0; i < numBodies; i++)
// Given body i: pair with every body[j] where j > i
for (let j: i32 = i + 1; i < numBodies; j++)
// Calculate the force the bodies apply to one another
const bI: i32 = i * 4
const bJ: i32 = j * 4
let f: f64[] = twoBodyForces(
// b0
data[bI], data[bI+1], data[bI+2], data[bI+3], // x,y,z,m
// b1
data[bJ], data[bJ+1], data[bJ+2], data[bJ+3], // x,y,z,m
);
// Add this pair's force on one another to their total forces applied x,y,z
// body0
ret[bI] = ret[bI] + f[0];
ret[bI+1] = ret[bI+1] + f[1];
ret[bI+2] = ret[bI+2] + f[2];
// body1
ret[bJ] = ret[bJ] + f[0];
ret[bJ+1] = ret[bJ+1] + f[1];
ret[bJ+2] = ret[bJ+2] + f[2];
// For each body, return the summ of forces all other bodies applied to it.
return ret;
【问题讨论】:
【参考方案1】:为了与 JS 更快的互操作,我建议尽可能使用类型化数组
export const FLOAT64ARRAY_ID = idof<Float64Array>();
export function nBodyForces(data: Float64Array): Float64Array ...
稍后在 javascript 方面:
const loader = require("assemblyscript/lib/loader");
const imports = ;
const wasm = await loader.instantiateStreaming(fetch("optimized.wasm"), imports);
const dataArray = [... your data ...]
const dataRef = wasm.__retain(wasm.__allocArray(wasm.FLOAT64ARRAY_ID, dataArray));
const resultRef = wasm.nBodyForces(dataRef);
const resultArray = wasm.__getFloat64Array(resultRef);
// release ARC resources
wasm.__release(dataRef);
wasm.__release(resultRef);
console.log("result: " + resultArray);
【讨论】:
好的,很有趣。看起来这是内存的分配/复制/释放。有没有办法用共享线性内存做到这一点?我正在尝试去 DomThread -> WebWorker -> Wasm -> 并返回。 在 Chrome 和 FF 中,我得到“wasm.__allocArray”不是一个函数。我尝试了运行时完整和一半(和默认)。我正在使用WebAssembly.instantiate(msg.wasmModule, importObj)
在 web worker 中实例化 wasm。
你应该使用“assemblyscript/lib/loader”而不是WebAssembly.instantiate
。加载程序暴露__allocArray
、__retain
__release
等,还包装了instantiateStreaming
/instantiate
。请参阅我的示例中的第一行
我看到了。没有 require() 和 webpack 就没有解决方案吗?
你可以试试这样的: 但我推荐使用 webpack 或 rollup以上是关于通过引用从 JS 传递数组以供 WASM 编辑?的主要内容,如果未能解决你的问题,请参考以下文章