Hello, this is a tech demo for:
- WebAssembly (Wasm) - a high performance web binary that allows execution of other languages on the web (C, C++, Rust, etc)
- AssemblyScript - a TypeScript subset that compiles to Wasm
- Web Workers - a separate thread to run our Wasm calculations
- Canvas API - drawing API for visualization
We'll apply this tech to the n-body problem. This is an astro-physics problem famous for being numerical (solved by a program) instead of analytical (solved by equations).
Essentially we'll throw some debris in a 3d space and watch it go spinny.
Why? The n-body problem is CPU intensive.
We will code those computations in WebAssembly (high performance C/Rust/AssemblyScript code), then run them in a separate thread.
Anectodally this is a 60% performance boost on mobile. It's also hard-core nerd-core.
Welcome to the back-end of the front-end - high-performance computing in the browser. This is crucial tech for the web as we move to WebVR.
If you have Node.js >= 8 installed:
# Install all the dev packages
npm install
# Build the Wasm using assemblyBuild.js and rollup.config.js
npm run build
# Serve the app
npm run serve
I'm always evaluating alternative tools to see what's coming in the future of technology.
gulpfile.js
builds the AssemblyScript to WebAssembly output.
- Why gulp? WebAssembly's AssemblyScript starter project uses it.
rollup.config.js
file builds the two js files needed for the web application: main.js
and workerWasm.js
.
-
Why so complicated? Memory management is still a thing. I spent a fair amount of time on this project trying to get it to work without a build toolchange. Passing arrays to/from AssemblyScript is dumb-hard (the unsatisfying kind of hard), and the best solution is to use AssemblyScript's loader, which is going to require a require().
-
Why rollup? I wanted something lighter-weight than
webpack
so tried rollup. Rollup was trivial to configure a 2nd entry point and requires("almost no attention").
This is a simulation hosted in a web browser, and expands on an AssemblyScript starter project from https://webassembly.studio
UI THREAD / WORKER THREAD
browser
|
index.html
|
main.js
|
nBodySimulator.js-----(web worker------workerWasm.js
| message passing) |
(draws to) nBodyForces.wasm
|
nBodyVisualizer.js
Files:
src/index.html - sets up the Canvas and UI, then runs main.js.
rollup.config.js - Build file for main.js and workerWasm.js
src/main.js - Entry point. Creates a nBodySystem(), passing a nBodyVisCanvas()
src/nBodyVisualizer.js - Simulation visualizers <=== ES6 Classes are standard and fun
src/nBodySimulator.js - Simulation loop and loads a nBodyForces implementation
src/workerWasm.js - Web worker to calculate in separate thread <=== WebAssembly and Web Workers
gulpfile.js - Gulpfile to process assembly/*
src/assembly/nBodyForces.ts - AssemblyScript code to calculate forces. <=== Sciency!
dist/assembly/nBodyForces.wasm - nBodyForces.ts --binaryen-transpiler--> wasm
dist/assembly/nBodyForces.wat - An "assembly code" text view of the compiled module <=== Nerd-core.
node_modules - Node.js stuff
package.json - Package versions and npm run commands
package-lock.json - Future proofs package installation
README.md - Turtles all the way down