-
Notifications
You must be signed in to change notification settings - Fork 0
/
server-side-wasm.html
298 lines (270 loc) · 11.6 KB
/
server-side-wasm.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Server-side WebAssembly</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/solarized.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match(/print-pdf/gi) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName('head')[0].appendChild(link);
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<h1>Server-side WebAssembly</h1>
<aside class="notes" data-markdown>
</aside>
</section>
<section>
<!--<h2>Node</h2>-->
<img style="border-style: none; box-shadow: none; height: 8em" src="static/nodejs-logo.png"/>
<aside class="notes" data-markdown>
I work on a node backend using a lot of CPU
WebAssembly was initially designed to be loaded from JS
Could we speed up our Node server code with WebAssembly?
</aside>
</section>
<section>
<!--<h2>Rust</h2>-->
<img style="border-style: none; box-shadow: none; height: 8em" src="static/rust-logo.png"/>
<aside class="notes" data-markdown>
Origin: Mozilla (working on next-gen Web browser)
- Built for safety & speed
- Does not require GC => good match for WebAssembly
</aside>
</section>
<section>
<!--<h2>Web Assembly</h2>-->
<img style="border-style: none; box-shadow: none; height: 8em" src="static/Web_Assembly_Logo.svg"/>
<aside class="notes" data-markdown>
* Efficient, low-level bytecode for the Web
* Fast to load and execute
* Safe and portable (similar to Java bytecode, sandboxed...)
* Open standard
* Intended as a compilation target (C/C++)
* No Garbage Collection (lightweight runtime)
* Currently good for Heavy CPU-bound number computations (e.g. Games)
</aside>
</section>
<section>
<section>
<!--<h2>Cloudflare</h2>-->
<img style="border-style: none; box-shadow: none; height: 8em" src="static/Cloudflare-logo.png"/>
<a href="https://blog.cloudflare.com/webassembly-on-cloudflare-workers/">https://blog.cloudflare.com/webassembly-on-cloudflare-workers/</a>
<aside class="notes" data-markdown>
Edge computing
Cloudflare Workers lets you deploy "serverless" JavaScript code directly to our 153-and-growing datacenters.
Your Worker handles your site's HTTP traffic directly at the location closest to your end user, allowing you to achieve lower latency and reduce serving costs.
</aside>
</section>
<section>
<h2>Benchmark</h2>
<p>Compute stuff from a Node App</p>
<ul>
<li>JS</li>
<li>Native</li>
<li>WebAssembly</li>
</ul>
<aside class="notes" data-markdown>
Native == neon
</aside>
</section>
<section>
<h3>Javascript</h3>
<pre><code class="js">
function sum(a, b) {
return a + b;
}
module.exports = {
sum,
};
</code></pre>
</section>
<section>
<h3>AssemblyScript/WASM</h3>
<pre><code class="ts">
export function sum(a: i32, b: i32): i32 {
return a + b;
}
</code></pre>
</section>
<section>
<h3>Rust/WASM</h3>
<pre><code class="rust">
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn sum(a: usize, b: usize) -> usize {
a + b
}
</code></pre>
<aside class="notes" data-markdown>
FFI == Foreign Function Interface
</aside>
</section>
<section>
<h3>Rust/Native</h3>
<pre><code class="rust">
#[macro_use]
extern crate neon;
use neon::prelude::*;
fn sum(mut cx: FunctionContext) -> JsResult<JsNumber> {
let a = cx.argument::<JsNumber>(0)?.value();
let b = cx.argument::<JsNumber>(1)?.value();
Ok(cx.number(a + b))
}
register_module!(mut cx, {
cx.export_function("sum", sum)?;
});
</code></pre>
</section>
<section>
<h3>Benchmark #1: Fibonacci</h3>
<img style="border-style: none; box-shadow: none; height: 8em" src="static/fibonacci-bench.png"/>
<aside class="notes" data-markdown>
- rust-ffi was the fastest
- ts-wasm was 2x slower than rust-ffi
- rust-wasm was 2x slower than rust-ffi
- js was 5x slower than rust-ffi
- js x 72,369 ops/sec ±0.76% (84 runs sampled)
- rust-ffi x 350,735 ops/sec ±1.50% (92 runs sampled)
- rust-wasm x 156,452 ops/sec ±0.62% (89 runs sampled)
- ts-wasm x 157,366 ops/sec ±0.46% (95 runs sampled)
</aside>
</section>
<section>
<h3>Benchmark #2: Parse TOML file</h3>
<img style="border-style: none; box-shadow: none; height: 8em" src="static/toml-bench.png"/>
<aside class="notes" data-markdown>
- rust-ffi was the fastest
- rust-wasm was 2x slower than rust-ffi
- js was 10x slower than rust-ffi
- js x 851 ops/sec ±9.29% (61 runs sampled)
- rust-ffi x 8,827 ops/sec ±8.13% (60 runs sampled)
- rust-wasm x 3,977 ops/sec ±9.86% (51 runs sampled)
</aside>
</section>
<section>
<h3>Benchmark #3: Compute SHA1</h3>
<img style="border-style: none; box-shadow: none; height: 8em" src="static/sha1-bench.png"/>
<aside class="notes" data-markdown>
- rust-ffi was the fastest
- rust-wasm was 5x slower than rust-ffi
- js was 237x slower than rust-ffi
- js x 7,821 ops/sec ±8.17% (76 runs sampled)
- rust-ffi x 1,852,213 ops/sec ±0.64% (94 runs sampled)
- rust-wasm x 382,354 ops/sec ±2.25% (89 runs sampled)
</aside>
</section>
<section>
<h3>Benchmark #4: Sum</h3>
<img style="border-style: none; box-shadow: none; height: 8em" src="static/sum-bench.png"/>
<aside class="notes" data-markdown>
- js was the fastest
- ts-wasm was 9x slower than js
- rust-wasm was 11x slower than js
- rust-ffi was 88x slower than js
- js x 741,975,701 ops/sec ±0.78% (88 runs sampled)
- rust-ffi x 8,424,746 ops/sec ±0.81% (96 runs sampled)
- rust-wasm x 70,611,062 ops/sec ±1.09% (94 runs sampled)
- ts-wasm x 84,443,591 ops/sec ±1.43% (93 runs sampled)
</aside>
</section>
<section>
<h2>Conclusion</h2>
<aside class="notes" data-markdown>
WebAssembly compared to JS:
- \+ much faster for heavy computations (low memory footprint & predictable performances)
- \- still, heavy FFI price
WASM programs operate in their own separate memory space, which means that it's necessary to copy data in and out of that space in order to operate on it.
WebAssembly compared to native:
- \- not as fast (e.g. lack of SIMD)
- \+ ship compiled version
- \+ simpler and faster FFI (e.g. AssemblyScript, Rust/Wasm Bindgen)
No direct system calls (they have to be provided by JS)
For most computations, simply stick to JS.
For heavy computations, when performance is critical, go native.
So, no WASM for our servers. But how about serverless?
</aside>
</section>
</section>
<section>
<section>
<h2>Standalone WebAssembly runtimes</h2>
<ul>
<li>Wasmer</li>
<li>Wasmtime</li>
<li>Lucet</li>
</ul>
<aside class="notes" data-markdown>
- WebAssembly is not irrelevant for server development
- There is a more radical/direct approach
Just-in-time compilation etc
</aside>
</section>
<section>
<img style="border-style: none; box-shadow: none; height: 8em" src="static/WASI-logo.png"/>
<aside class="notes" data-markdown>
- The WebAssembly System Interface
- modular system interface for WebAssembly
- focused on security and portability
</aside>
</section>
<section>
<img style="border-style: none; box-shadow: none; height: 8em" src="static/fastly-logo.png"/>
<a href="https://www.fastly.com/blog/announcing-lucet-fastly-native-webassembly-compiler-runtime">https://www.fastly.com/blog/announcing-lucet-fastly-native-webassembly-compiler-runtime</a>
<aside class="notes" data-markdown>
Example of performance to expect:
- Instantiate WASM module in under 50 microseconds (100x faster than Node)
- A few kb of memory overhead (10,000x less than Node)
Benchmarks don't make sense. The products don't compare
</aside>
</section>
<section>
<img style="border-style: none; box-shadow: none; height: 8em" src="static/future.png"/>
<aside class="notes" data-markdown>
- Run your cloud functions at a fraction of the current cost
- Faster than ever, low memory footprint
- Pick your favorite language
- Universal executable: build once, run anywhere
- Don't have to negotiate on security either (isolated execution, sandbox)
</aside>
</section>
</section>
<section>
<h2>Thank you!</h2>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// More info https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
history: true,
// More info https://github.com/hakimel/reveal.js#dependencies
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{
src: 'plugin/highlight/highlight.js', async: true, callback: function () {
hljs.initHighlightingOnLoad();
}
}
]
});
// Shows the slide number using default formatting
Reveal.configure({ slideNumber: true });
</script>
</body>
</html>