What’s WebAssembly?
New binary format
Run compiled programs (C, C++, Rust) on a
browser
Works alongside Javascript
Performance and flexibility
API
Slide 8
Slide 8 text
Looks interesting, right?
Slide 9
Slide 9 text
The Journey
Slide 10
Slide 10 text
BrazilJS 2015
Slide 11
Slide 11 text
No content
Slide 12
Slide 12 text
+
Slide 13
Slide 13 text
JSConfEU 2017
+
Slide 14
Slide 14 text
No content
Slide 15
Slide 15 text
+
Slide 16
Slide 16 text
The journey begun
Slide 17
Slide 17 text
Our POC: John Conway’s
game of life
Slide 18
Slide 18 text
Game of life
ZERO PLAYER game
Matrix, each cell can be
either DEAD or ALIVE
The only external input
is the INITIAL STATE
Alive Dead
Slide 19
Slide 19 text
Game of life
CURRENT STATUS NEIGHBOURS COUNT NEXT STATUS
<
( )
>
Slide 20
Slide 20 text
A good example if we use
big matrix
Slide 21
Slide 21 text
Our algorithm
1.Create a big matrix randomly filled with 0
and 1
2.Render the initial state and send it to the
environment component
3.Generate and render the next state (loop)
Slide 22
Slide 22 text
Three approaches
}Same algorithm
O(n*m) complexity
Render part in common
VANILLA JS
WEBASSEMBLY
WEB WORKERS
Slide 23
Slide 23 text
Vanilla JS
Slide 24
Slide 24 text
A lot of functions
function getNextState(currentState, width, height) {
…
}
function getLineCount(currentState, column, bounds) {
…
}
function createBounds(width, height) {
…
}
…
Slide 25
Slide 25 text
Results
Slide 26
Slide 26 text
Vanilla JS results
Next state calculation between 9ms and 4ms
Slide 27
Slide 27 text
Why so many variations
in the results?
JIT
Slide 28
Slide 28 text
JIT: just in time compiler
Cold code -> Interpreter
Warm code -> baseline compiler
Hot code -> optimising compiler
Slide 29
Slide 29 text
JIT: just in time compiler
Cold code -> Interpreter
Warm code -> baseline compiler
Hot code -> optimising compiler
Slide 30
Slide 30 text
JIT: just in time compiler
Cold code -> Interpreter
Warm code -> baseline compiler
Hot code -> optimising compiler
WebAssembly is fast
Parse Compile Optimize Execute GC
Decode
Compile
+
Optimize
Execute
JS
WASM
Slide 34
Slide 34 text
WebAssembly is fast
WASM is more compact -> Faster FETCH of the source
WASM is closer to machine code -> Faster DECODING,
COMPILING and OPTIMISING
No need to RE-OPTIMISE
No garbage collection
Slide 35
Slide 35 text
So WebAssembly sounds
fast, let’s see how to use
it
Slide 36
Slide 36 text
How to run WASM modules
Current situation: not possible to run WASM
modules on their own
Need for some Javascript glue
Slide 37
Slide 37 text
WebAssembly JS API
1. Fetch the module binary
2. Instantiate it
3. Access exported functionalities
Slide 38
Slide 38 text
fetch('module.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
// Do something with the compiled results!
});
Slide 39
Slide 39 text
How to generate a WASM
file
Slide 40
Slide 40 text
Compile C to WASM
+
JS WASM
v 1.37
emcc environment.c -o environment.js -s WASM=1
Slide 41
Slide 41 text
Then we can simply
import the generated JS
code as a module
Slide 42
Slide 42 text
Export functions to JS
Keyword EMSCRIPTEN_KEEPALIVE
EMSCRIPTEN_KEEPALIVE
void getNextState(int width, int
height) {
…
}
Expose only the interface of the WASM module to JS
Slide 43
Slide 43 text
What about WebAssembly
memory?
How can we access it?
Slide 44
Slide 44 text
We want to reproduce the
same logic of our Vanilla
JS implementation in C
Slide 45
Slide 45 text
The C environment has to
be initialised with the first
state of the game
Slide 46
Slide 46 text
Memory management
Emscripten provide three useful functions
to manage WebAssembly memory
_malloc(memoryNeeded)
getValue(ptr, type)
setValue(ptr, value, type)
Slide 47
Slide 47 text
Our JS code has a
reference to the C memory
containing the next state
Write
Allocate
Read
Write
Slide 48
Slide 48 text
Too many memory
access from JS
Slide 49
Slide 49 text
Reduce memory access
One memory allocation on loading
One memory write on loading
One memory read on each iteration
Slide 50
Slide 50 text
We measured the
performance again…
Slide 51
Slide 51 text
The WASM
implementation was still
slower
Slide 52
Slide 52 text
WebAssembly performance
Still slightly slower than Vanilla JS
Slide 53
Slide 53 text
Why??
Slide 54
Slide 54 text
Why was WASM slower?
Further investigation
Simple counter test
Results confirmed
Slide 55
Slide 55 text
JIT handover
Slide 56
Slide 56 text
“Currently, calling a WebAssembly function
in JS code is slower than it needs to be.
The JIT doesn’t know how to deal directly
with WebAssembly, so it has to route the
WebAssembly to something that does.
…
This can be up to 100x slower than it
would be if the JIT knew how to handle it
directly.
”
Lin Clark
Slide 57
Slide 57 text
Web Workers
Slide 58
Slide 58 text
Parallel threads
Promise.all()
Slide 59
Slide 59 text
Results
Slide 60
Slide 60 text
Web workers results
Next state calculation between 3ms and 2ms
Shared Array Buffer?
Slide 61
Slide 61 text
The future of
WebAssembly
Slide 62
Slide 62 text
Browser support
SHIPPED 11 SOON
Slide 63
Slide 63 text
Future features
Formal Specification
Threads supports
SIMD acronym to Single Instruction Multiple Data (back to Stage 3 on TC39)
Exception handling
Garbage collection
Direct DOM access
ES6 Module integration
Slide 64
Slide 64 text
Learn more
https://github.com/eliamaino-fp/webassembly-js
https://braziljs.org/blog/iniciando-com-webassembly-parte-1/
http://devnaestrada.com.br/2017/07/07/web-assembly.html
https://github.com/mbasso/awesome-wasm/
twitter.com/wmsbill
twitter.com/eliamain