Give your Web App
Superpowers
with WebAssembly
and Friends
May 11, 2016 - Brad Nelson / @flagxor
Pushing the Envelop in 2016
- Average website (2.39MB)
= Doom (2.39MB)
- Moore's Law
- Mobile
Pushing the Envelop on the Web
-
JavaScript performance is inconsistent and plateauing
- The DOM is inherently slow
- Both require browsers to infer and guess
Virtues of the Web
- Open
- Portable
- Secure
- Ephemeral
- What's missing?
Native Code
- Runs really fast
- Close to the metal
- Low power
- Has access to "native" APIs
- All the languages: C++, Java, Python...
- Threads + Shared Memory
- SIMD
GNU Image Manipulation Program (GIMP)
Android → ChromeOS
But I'm a JavaScript developer...
- C/C++ libraries
- Codecs
- Widgets
How to bring Native Code to the Web?
Native Client
- Run machine code, safely
- Portable variant
- Fast
- 80-95% of Raw Native
- SIMD support
- Threads and shared memory
- Shared Libraries
- JIT Support
-
Mature and powerful, but Chrome only
Jargon
-
Native Client → NaCl
-
Portable Native Client
→ PNaCl
What makes NaCl safe?
- Two Sandboxes!
- Outer Process Sandbox
- Inner Static Verification Sandbox
Process Sandbox (NaCl)
|
|
|
⤢ |
Renderer Process |
↔ |
NaCl Process |
OS
|
↔ |
|
↔ |
Renderer Process |
|
|
|
|
|
⤡ |
Renderer Process |
|
|
Software Fault Isolation
(NaCl Inner Sandbox)
- Verify before run
- Disassemble everything
- Limit instructions
- Restrict what code can execute
(Control Flow Integrity)
- Restrict what data can be accessed
(Data Integrity)
- Restrict I/O interface
Software Fault Isolation
(NaCl Inner Sandbox)
0 - 256MB |
Code |
256MB - 1GB / 4GB |
Data |
How to make it run everywhere (sorta)?
Emscripten / Asm.js
- C/C++ compiled to JavaScript
- Use ArrayBuffer as a C/C++ heap
- High percentage of Raw Native
- Faster in some browsers than others
- Synchronous access to JS + the DOM
-
Portable, but missing some features
Jargon
-
Emscripten
→ [Put into] script [become]
-
Asm.js →
Assembly Language as JavaScript
JavaScript "Type Declarations"
- float64 → +(xxx)
- float32 → Math.fround(xxx)
- int32 → (xxx)|0
- uint32 → (xxx)>>>0
- TypedArray → pointers
function MyAsmModule(stdlib, foreign, heap) {
"use asm";
var HEAPU8 = new Uint8Array(heap);
function strlen(ptr) {
ptr = ptr|0;
var curr = 0;
curr = ptr;
while (HEAP8[curr]|0 != 0) {
curr = (curr + 1)|0;
}
return (curr - ptr)|0;
}
...
Web Assembly
- Cross-browser binary Native Code
- Open W3C Collaboration
- LLVM backend upstream
- Start with Asm.js level features
- Roadmap for all the things!
- Threads + Shared Memory
- SIMD
- Hardware Fault Interception
- Memory mapping
- Dynamic Linking / Shared Libraries
- JIT Support
(func $aligned (result i32)
(local i32 i32 i32)
(set_local 0 (i32.const 10))
(label
(loop
(if
(i32.eq (get_local 0) (i32.const 0))
(break 0)
)
(set_local 2
(i32.mul (get_local 0) (i32.const 4)))
(i32.store (get_local 2) (get_local 0))
...
Make friends with JavaScript!
-
SIMD → Single Instruction, Multiple Data
- Expose SSE/AVX/Neon to the Web
- 128-bit SIMD Types
- SIMD.js - TC39 Stage 3
function vec4average(a) {
var a_length = a.length;
var sum = SIMD.Float32x4.splat(0.0);
for (var i = 0; i < a_length; i += 4) {
sum = SIMD.Float32x4.add(
sum, SIMD.Float32x4.load(a, i));
}
return SIMD.div(sum, SIMD.Float32x4.splat(n));
}
SharedArrayBuffers
- Shared Memory for JavaScript
- Web Workers see a shared ArrayBuffer
- Atomics + Futexes
- Gateway to Wasm shared memory
- TC39 Stage 2
Threads
in JavaScript!?!
- Use all the cores!
- postMessage is SLOW!
- Fast synchronization
- Blocking on background threads!
- Different concurrency models
- C/C++ code expects threads
Challenges
- Concurrency is hard
- but you know that already
- What about the main thread?
- Shared Memory + Web APIS
- Will it change how Web apps work?
Expect more from the Web Platform
- Vibrant platforms let developers innovate!