|
import fs from "fs"; |
|
|
|
// ----------------------- |
|
// HELPERS |
|
// ----------------------- |
|
|
|
let measures = {}; |
|
|
|
let measureLabel = null; |
|
let measureStart = null; |
|
|
|
function startMeasure(label) { |
|
measures[label] = performance.now(); |
|
} |
|
|
|
function endMeasure(label) { |
|
let start = measures[label]; |
|
let res = performance.now() - start; |
|
console.log(`==> MEASURE [${label}]: ${res.toFixed(6)}ns`); |
|
} |
|
|
|
function randFloat() { |
|
return Math.random(); |
|
} |
|
|
|
function fillZero(data) { |
|
let length = data.length; |
|
for (let i=0; i<length; i++) { |
|
data[i] = 0; |
|
} |
|
} |
|
|
|
// ----------------------- |
|
// WASM INSTANCE |
|
// ----------------------- |
|
|
|
const DATA_SIZE = 300000*4; |
|
|
|
// == INITIALIZE |
|
|
|
startMeasure("wasm instance"); |
|
|
|
const buf = fs.readFileSync('./example.wasm') |
|
const res = await WebAssembly.instantiate(buf, {}) |
|
const { |
|
mulExplicitSimdFloat64, |
|
mulImplicitSimdFloat64, |
|
sumAll, |
|
memory |
|
} = res.instance.exports; |
|
|
|
await memory.grow(460); |
|
|
|
endMeasure("wasm instance"); |
|
|
|
// == MEM ALLOC |
|
|
|
const requiredMemory = Float64Array.BYTES_PER_ELEMENT*DATA_SIZE; |
|
|
|
console.log(`=> Data size: ${DATA_SIZE}`); |
|
console.log("=> Memory available:", memory.buffer.byteLength); |
|
console.log("=> Required memory: ", requiredMemory*3); |
|
|
|
const bdata1 = new Float64Array(memory.buffer, 0, DATA_SIZE); |
|
const bdata2 = new Float64Array(memory.buffer, DATA_SIZE, DATA_SIZE); |
|
const boutput = new Float64Array(memory.buffer, DATA_SIZE*2, DATA_SIZE); |
|
|
|
|
|
// == MEM INIT |
|
|
|
startMeasure("mem init"); |
|
|
|
// Populate data |
|
const data1 = Array.from({length: DATA_SIZE}, randFloat); |
|
const data2 = Array.from({length: DATA_SIZE}, randFloat); |
|
endMeasure("mem init"); |
|
|
|
startMeasure("mem fill"); |
|
bdata1.set(data1); |
|
bdata2.set(data2); |
|
console.log("=> Data Size:", bdata1.byteLength); |
|
endMeasure("mem fill"); |
|
|
|
|
|
startMeasure("run JS"); |
|
|
|
// Calculate it on JS |
|
let result = (function (output, data1, data2) { |
|
for (let i=0; i<DATA_SIZE; i++) { |
|
output[i] = data1[i]*data2[i]; |
|
} |
|
|
|
let total = 0.0; |
|
let length = output.length; |
|
for (let i=0; i<length; i++) { |
|
total += output[i]; |
|
} |
|
return total; |
|
})(boutput, bdata1, bdata2); |
|
endMeasure("run JS"); |
|
console.log(`=> Result JS: ${result.toFixed(4)}`); |
|
|
|
fillZero(boutput); |
|
|
|
// Call the function and display the results. |
|
|
|
startMeasure("run WASM E"); |
|
mulExplicitSimdFloat64(boutput.byteOffset, bdata1.byteOffset, bdata2.byteOffset, DATA_SIZE) |
|
result = sumAll(boutput.byteOffset, DATA_SIZE); |
|
console.log(`=> Result WASM[E]: ${result.toFixed(4)}`); |
|
endMeasure("run WASM E"); |
|
|
|
fillZero(boutput); |
|
|
|
startMeasure("run WASM I"); |
|
mulImplicitSimdFloat64(boutput.byteOffset, bdata1.byteOffset, bdata2.byteOffset, DATA_SIZE) |
|
result = sumAll(boutput.byteOffset, DATA_SIZE); |
|
console.log(`=> Result WASM[I]: ${result.toFixed(4)}`); |
|
endMeasure("run WASM I"); |