1// Runs the CPU-bound methods (plain JS and both WASM kernels) off the main
2// thread — naive JS/WASM at n=2048 take long enough (~10s) to freeze the tab
3// otherwise. Regenerates inputs from the (n, seed) pair rather than
4// receiving them over postMessage, since that's cheaper than structured-
5// cloning multi-megabyte Float64Arrays for every run.
6import { generateMatrix } from './random'
7import { jsMatmul } from './jsMatmul'
8import { wasmNaiveMatmul, wasmBlockedMatmul } from './wasmMatmul'
9import type { MatmulMethod } from './types'
11const METHODS: Record<string, MatmulMethod> = {
12 js: jsMatmul,
13 'wasm-naive': wasmNaiveMatmul,
14 'wasm-blocked': wasmBlockedMatmul,
15}
17export interface WorkerRequest {
18 id: number
19 methodId: string
20 n: number
21 seedA: number
22 seedB: number
23}
25export type WorkerResponse =
26 | { id: number; ms: number; sample: number }
27 | { id: number; error: string }
29self.onmessage = async (e: MessageEvent<WorkerRequest>) => {
30 const { id, methodId, n, seedA, seedB } = e.data
31 try {
32 const method = METHODS[methodId]
33 if (!method?.run) throw new Error(`Unknown method: ${methodId}`)
34 const a = generateMatrix(n, seedA)
35 const b = generateMatrix(n, seedB)
36 const { ms, sample } = await method.run(n, a, b)
37 self.postMessage({ id, ms, sample } satisfies WorkerResponse)
38 } catch (err) {
39 self.postMessage({ id, error: err instanceof Error ? err.message : String(err) } satisfies WorkerResponse)
40 }
41}