Jeremy Magland Clear results when the thread count changes
| .github | |
| blis | |
| native | |
| public | |
| src | |
| wasm | |
| .gitignore | |
| .oxlintrc.json | |
| CLAUDE.md | |
| index.html | |
| package-lock.json | |
| package.json | |
| README.md | |
| tsconfig.app.json | |
| tsconfig.json | |
| tsconfig.node.json | |
| vite.config.ts |
matmul-bench#
Compares matrix-matrix multiply (GEMM) performance across implementations running in the browser, plus a native reference measured outside it.
Live: https://concept-collection.github.io/matmul-bench/
Methods:
- JavaScript/TypeScript — plain triple loop over
Float64Array(f64), no special-casing. The "no special effort" baseline. - WebGPU — a tiled compute shader (f32; WGSL has no double precision).
- WASM from custom C — naive, blocked+SIMD (
f64x2,-msimd128), and a threaded (WASM pthreads) version of the blocked+SIMD kernel, built with emscripten (f64). The threaded one needs cross-origin isolation. - libFLAME/BLIS in WASM — a real BLAS (
dgemmvia libFLAME + BLIS) compiled to WebAssembly, single-threaded and multi-threaded (WASM pthreads), from libflame2wasm (f64). The threaded build needs cross-origin isolation (SharedArrayBuffer), supplied on GitHub Pages by a vendored service worker. - Native LAPACK/OpenBLAS — a fixed reference table from
dgemmrun outside the browser (native/).
Develop#
npm install
npm run dev # local dev server (sends COOP/COEP for threaded methods)
wasm/build-wasm.sh # rebuild wasm/dist/matmul.* + public/matmul/matmul_mt.*
# (needs emsdk)
blis/build-blis-wasm.sh # rebuild public/matmul/matmul_blis_{st,mt}.* (needs emsdk
# + the prebuilt .a files from a sibling libflame2wasm)
npm run build # tsc -b && vite build
The libFLAME/BLIS WASM artifacts under public/matmul/ are committed (they link
~30 MB of prebuilt static libraries that live in a separate
libflame2wasm checkout), so the
GitHub Pages build doesn't rebuild them. The threaded custom module
(public/matmul/matmul_mt.*) is built in CI from wasm/matmul.c.
Native reference#
native/build.sh
OPENBLAS_NUM_THREADS=1 native/bench_native 128 256 512 1024 2048
OPENBLAS_NUM_THREADS=12 native/bench_native 128 256 512 1024 2048
Hand-copy the results into src/data/nativeReference.ts.