1

在 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;
}

4

1 回答 1

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);
于 2019-09-14T08:26:27.837 回答