diff --git a/client/speed.js b/client/speed.js index fbf801a..bc91a27 100644 --- a/client/speed.js +++ b/client/speed.js @@ -1,4 +1,70 @@ +async function init_test() { + const memory = new WebAssembly.Memory({ + initial: 32, + maximum: 100, + shared: true, + }); + + const results = await WebAssembly.instantiateStreaming(fetch('wasm/multi.wasm'), { + env: { 'memory': memory } + }); + + const nworkers = navigator.hardwareConcurrency; + const heap_base = results.instance.exports.alloc(0); + const buf_offset = results.instance.exports.alloc(1024); + const workers = []; + const sab = new SharedArrayBuffer(nworkers * 4); + const flags = new Int32Array(sab); + let done = 0; + + for (let i = 0; i < nworkers; ++i) { + const w = new Worker('wasm_worker.js'); + workers.push(w); + } + + for (let i = 0; i < nworkers; ++i) { + workers[i].onmessage = () => { + ++done; + if (done % nworkers === 0) { + console.log('init done'); + + for (let j = 0; j < nworkers; ++j) { + workers[j].onmessage = () => { + ++done; + + if (done % nworkers === 0) { + console.log('work done'); + console.log(new Int32Array(memory.buffer, buf_offset, nworkers)); + } + } + + workers[j].postMessage({ + 'type': 1, + 'num': 10, + }); + } + } + } + + workers[i].postMessage({ + 'type': 0, + 'thread_id': i, + 'memory': memory, + 'stack_base': heap_base, + 'buffer_offset': buf_offset, + 'flags': flags + }); + } + +// const results = await WebAssembly.instantiateStreaming(fetch('wasm/multi.wasm')); + +// state.wasm.exports = results.instance.exports; +// state.wasm.exports.memory.grow(4096); +} + async function init_wasm(state) { + await init_test(); + const results = await WebAssembly.instantiateStreaming(fetch('wasm/lod.wasm')); state.wasm.exports = results.instance.exports; diff --git a/client/wasm/compile_command b/client/wasm/compile_command new file mode 100644 index 0000000..b496251 --- /dev/null +++ b/client/wasm/compile_command @@ -0,0 +1 @@ +clang -Oz --target=wasm32 -nostdlib -msimd128 -mbulk-memory -matomics -Wl,--no-entry,--import-memory,--shared-memory,--max-memory=$((1024 * 1024 * 1024)) -z stack-size=$((1024 * 1024)) multi.c -o multi.wasm diff --git a/client/wasm/lod.c b/client/wasm/lod.c index e63d270..bed8a70 100644 --- a/client/wasm/lod.c +++ b/client/wasm/lod.c @@ -7,6 +7,16 @@ extern char __heap_base; static int allocated_static; static int allocated_dynamic; +void +set_sp(void *sp) +{ + __asm__ volatile( + "local.get 0\n" + "global.set __stack_pointer\n" + : : "r"(sp) + ); +} + void free_static(void) { diff --git a/client/wasm/lod.wasm b/client/wasm/lod.wasm index 63161d4..7f218d7 100755 Binary files a/client/wasm/lod.wasm and b/client/wasm/lod.wasm differ diff --git a/client/wasm/multi.c b/client/wasm/multi.c new file mode 100644 index 0000000..20765cb --- /dev/null +++ b/client/wasm/multi.c @@ -0,0 +1,37 @@ +#include + +extern char __heap_base; + +static int allocated; + +void +set_sp(char *sp) +{ + __asm__ __volatile__( + ".globaltype __stack_pointer, i32\n" + "local.get %0\n" + "global.set __stack_pointer\n" + : : "r"(sp) + ); +} + +void * +alloc(int size) +{ + void *result = &__heap_base + allocated; + allocated += size; + return(result); +} + +static void +impl(int *buffer, int index, int number) +{ + buffer[index] = number; +} + +void +write_a_number(int *buffer, int index, int number) +{ + int n = number * 2; + impl(buffer, index, n); +} diff --git a/client/wasm/multi.wasm b/client/wasm/multi.wasm new file mode 100755 index 0000000..01e32fb Binary files /dev/null and b/client/wasm/multi.wasm differ diff --git a/client/wasm_worker.js b/client/wasm_worker.js new file mode 100644 index 0000000..0e0ff7c --- /dev/null +++ b/client/wasm_worker.js @@ -0,0 +1,40 @@ +let thread_id = null; +let buf_offset = null; +let exports = null; +let flags = null; + +function done() { + postMessage('done'); +} + +async function init_wasm(tid, memory, offset, notify_flags, stack_base) { + thread_id = tid; + buf_offset = offset; + + const result = await WebAssembly.instantiateStreaming(fetch('wasm/multi.wasm'), { + env: { 'memory': memory } + }); + + exports = result.instance.exports; + //console.log(tid, 'init'); + exports.set_sp(stack_base - thread_id * 4096); + + flags = notify_flags; + done(); +} + +function do_work(num, callback) { + //console.log(thread_id, 'work'); + exports.write_a_number(buf_offset, thread_id, thread_id * num); + done(); +} + +onmessage = (e) => { + if (e.data.type === 0) { + init_wasm(e.data.thread_id, e.data.memory, e.data.buffer_offset, e.data.flags, e.data.stack_base); + } else if (e.data.type === 1) { + do_work(e.data.num); + } +} + +