Alon Zakai / 2016
We begin in ancient times...
WebAssembly (wasm) is coming, we need ways to compile to it
Two parallel efforts are begun:
1. LLVM WebAssembly backend: from scratch, not limited by asm.js (lacks i64s, etc.); long-term effort (still in progress today)
2. asm2wasm: asm.js → wasm; a quick hack to get something working
Indeed, we quickly got asm2wasm up and running:
LLVM IR | → | asm.js backend | → | JS optimizer | → | asm2wasm | → | wasm |
(only thing that changed is in bold)
asm2wasm is part of Binaryen, which has a WebAssembly optimizer
Can run standalone, also asm2wasm can run it in parallel:
LLVM IR | → | asm.js backend | → | JS optimizer | → | asm2wasm & wasm optimizer | → | wasm |
WebAssembly optimizer improves, removes need for JS one:
LLVM IR | → | asm.js backend | → | JS optimizer | → | asm2wasm & wasm optimizer |
→ | wasm |
Which brings us to this:
LLVM IR | → | asm.js backend | → | asm2wasm & wasm optimizer |
→ | wasm |
Note: we don't need to emit proper JS or asm.js anymore...
wasm-only mode: Adds special intrinsics to the asm.js backend's output, for i64s and other things asm.js couldn't handle well
function truncate(x) {
x = i64(x); // declare param as i64
return i64_trunc(x) | 0; // truncate to low 32 bits
}
→ asm2wasm no longer limited by asm.js, just like WebAssembly backend
→ current state of asm2wasm toolchain:
LLVM IR | → | "asm.js" backend | → | asm2wasm & wasm optimizer |
→ | wasm |
Box2D code size measurements
phase | gzipped size (K) | ||
asm.js | 55.3 | ||
+ asm2wasm | 50.0 | (a) | |
+ wasm opts | 45.2 | ||
js opts | 44.1 | ||
wasm-only | 43.1 | (b) |
(lower is better)
(a) going to wasm is a 10% improvement
(b) the rest add a further 14%
Box2D speed measurements
phase | time (seconds) | ||
asm.js | 5.97 | ||
+ asm2wasm | 5.66 | (a) | |
+ wasm opts | 5.28 | ||
js opts | 5.24 | (b) | |
wasm-only | 5.24 |
(lower is better)
(a) going to wasm is a 5% improvement
(b) the rest add a further 7%
Hmm, wasm-only doesn't help much here...
An i64-specific benchmark, corrections-i64:
phase | time (seconds) | ||
asm.js | 28.46 | ||
+ asm2wasm | 13.21 | (a) | |
+ wasm opts | 12.99 | ||
js opts | 12.88 | ||
wasm-only | 6.88 | (b) |
(lower is better)
(a) asm2wasm uses i64s in runtime, ~2X faster
(b) wasm-only uses the full power of WebAssembly, i64s everywhere, for a further ~2X
Which brings us to The End, and the moral of our story: