index.html.raw (11116B)
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <title>WebAssembly and Emscripten</title> 5 <meta name="viewport" content="width=device-width" /> 6 7 <!-- Import highlight.js script and style sheet --> 8 <script id="highlight.js" src=" 9 https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js" 10 ></script> 11 <link rel="stylesheet" href=" 12 https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/vs.css" 13 > 14 15 <!-- Custom style --> 16 <style> 17 html { height: 100vh; width: 98vw; margin: 0 2vw 0 0; font-family: sans-serif; } 18 h1 { 19 font-size: 3.5vw; 20 background-color: #a4b5c5; 21 margin: 0; 22 padding: 2px 10px 2px 10px; 23 border-bottom-left-radius: 6px; 24 border-bottom-right-radius: 6px; 25 } 26 body { font-size: 2.2vw; height: 100%; width: 100%; } 27 a, a:visited { color: #0f2899; text-decoration: none; } 28 a:hover { text-decoration: underline; } 29 figcaption { text-align: center; font-size: 1.5vw; } 30 em { font-style: normal; color: blue; } 31 32 .slide { outline: none; height: 100vh; width: 100%; } 33 .slide { 34 display: flex; 35 flex-direction: column; 36 justify-content: space-between; 37 } 38 .slide ul { margin-left: 1.5vw; } 39 .slide ol { margin-left: 1.5vw; } 40 .slide p { margin-left: 1.5vw; } 41 .slide li { margin: 3.0vh 0; } 42 43 .slide.titlepage p, a { text-align: center; } 44 .slide.titlepage span.title { font-size: 3.6vw; font-weight: bold; } 45 .slide.titlepage span.author { } 46 47 48 .slide div.centertext { text-align: center; margin: auto; width: 60%; } 49 50 .columns { 51 display: flex; 52 flex-direction: row; 53 justify-content: space-between; 54 align-items: center; 55 } 56 57 .footer { 58 font-size: 1.8vw; 59 padding: 2px 10px 2px 10px; 60 border-top-left-radius: 6px; 61 border-top-right-radius: 6px; 62 background-color: #a4b5c5; 63 } 64 .footer table { width: 100%; } 65 .footer-title { font-weight: bold; } 66 .footer-link { text-align: right; } 67 68 #bench { 69 border-collapse: collapse; 70 width: 99%; 71 } 72 #bench th, #bench td { 73 border: 1px solid black; 74 padding: 5px; 75 text-align: center; 76 } 77 #bench th { white-space: normal; } 78 </style> 79 <meta charset="utf-8"> 80 </head> 81 82 <body> 83 84 <div class="slide titlepage" tabindex="-1" 85 style="background-image: url('images/cpp-in-the-web.png'); 86 background-position: center; 87 background-repeat: no-repeat; 88 background-size: 70%; 89 background-color: rgba(255, 255, 255, 0.85); 90 background-blend-mode: overlay;"> 91 92 <p></p> 93 94 <p><span class="title">WebAssembly and Emscripten</span></p> 95 <p><span class="author">Sebastiano Tronto</span></p> 96 <p><span class="event">ALTEN Advanced Software Evening</span></p> 97 98 </div> 99 100 101 <div class="slide" tabindex="-1"> 102 <h1>Your browser runs code</h1> 103 104 <div class="columns"> 105 106 <div style="text-align: center;"> 107 <input id="aInput" size=10 style="font-size: 24px;"> 108 <br> 109 + 110 <br> 111 <input id="bInput" size=10 style="font-size: 24px;"> 112 <br> 113 <button id="resultButton" style="font-size: 24px;">=</button> 114 <br> 115 <span id="resultText" style="font-size: 30px;"></span> 116 </div> 117 118 <pre><code class="language-javascript" 119 style="border: 0.2vw solid; font-size: 2.2vw;"> 120 var aInput = document.getElementById("aInput"); 121 var bInput = document.getElementById("bInput"); 122 var button = document.getElementById("resultButton"); 123 var resultText = document.getElementById("resultText"); 124 125 button.addEventListener("click", () => { 126 var a = Number(aInput.value); 127 var b = Number(bInput.value); 128 resultText.innerText = a + b; 129 }); 130 </code></pre></div> 131 132 </div> 133 134 135 136 <div class="slide" tabindex="-1"> 137 <h1>WebAssembly</h1> 138 139 <div class="columns"> 140 141 <a href="https://webassembly.org/"> 142 <img src="images/wasm-logo.png" style="width: 80%;"> 143 </a> 144 145 <div> 146 <p style="text-align: center;"> 147 WASM first appeared in 2017 as a more performant language for the browser. 148 </p> 149 150 <p style="text-align: center;"> 151 It runs in a VM and can interact with JavaScript, but not with the DOM. 152 </p> 153 </div> 154 155 </div> 156 </div> 157 158 <div class="slide" tabindex="-1"> 159 <h1>WebAssembly - code example</h1> 160 161 <div class="columns"> 162 163 <pre><code class="language-wasm" 164 style="border: 0.2vw solid; font-size: 2.1vw;"> 165 (func (param i64) (result i64) 166 local.get 0 167 i64.eqz 168 if (result i64) 169 i64.const 1 170 else 171 local.get 0 172 local.get 0 173 i64.const 1 174 i64.sub 175 call 0 176 i64.mul 177 end) 178 </code></pre> 179 180 <div></div> 181 182 </div> 183 </div> 184 185 <div class="slide" tabindex="-1"> 186 <h1>WebAssembly - code example</h1> 187 188 <div class="columns"> 189 190 <pre><code class="language-wasm" 191 style="border: 0.2vw solid; font-size: 2.1vw;"> 192 (func (param i64) (result i64) 193 local.get 0 194 i64.eqz 195 if (result i64) 196 i64.const 1 197 else 198 local.get 0 199 local.get 0 200 i64.const 1 201 i64.sub 202 call 0 203 i64.mul 204 end) 205 </code></pre> 206 207 <div> 208 Same thing in Python: 209 <pre><code class="language-python" 210 style="border: 0.2vw solid; font-size: 2.1vw;"> 211 def f(n): 212 if n == 0: 213 return 1 214 else 215 return n * f(n-1) 216 </code></pre> 217 </div> 218 219 </div> 220 </div> 221 222 <div class="slide" tabindex="-1"> 223 <h1>Emscripten</h1> 224 225 <a href="https://emscripten.org/index.html"> 226 <img src="images/emscripten-logo-full.png"> 227 </a> 228 229 <p style="text-align: center;"> 230 <strong> 231 "Emscripten is a complete compiler toolchain to WebAssembly, using LLVM, 232 with a special focus on speed, size, and the Web platform." 233 </strong> 234 </p> 235 236 </div> 237 238 <div class="slide" tabindex="-1"> 239 <h1>Hello, world!</h1> 240 241 <div class="columns"> 242 243 <ol> 244 <li>Write an Hello World program in C or C++</li> 245 <li>Compile with <pre>emcc -o index.html hello.c</pre></li> 246 <li>Run a web server and 247 <a href="./examples/1-hello-world">open a browser</a>!</li> 248 </ol> 249 250 <img src="images/meme.png" style="width: 35%;"> 251 252 </div> 253 </div> 254 255 <div class="slide" tabindex="-1"> 256 <h1>Writing a library</h1> 257 258 <i>Thanks Emscripten, we'll write our own HTML!</i> 259 260 <div class="columns"> 261 262 <img src="./images/sum.jpg" style="width: 70%;"> 263 264 <div> 265 <ul> 266 <li><strong>Goal:</strong> 267 write a library with a function to sum two numbers, 268 and use it in a simple web page</li> 269 <li>See <a href=./examples/2-sum>examples/2-sum</a></li> 270 <li>Some extra options are needed:</li> 271 </ul> 272 <pre><code class="language-shell"> 273 emcc -sEXPORTED_FUNCTIONS=_sum \ 274 -sMODULARIZE \ 275 -sEXPORT_NAME=SumLibrary \ 276 -o sum_library.mjs \ 277 sum_library.c 278 </code></pre> 279 </div> 280 281 </div> 282 </div> 283 284 <div class="slide" tabindex="-1"> 285 <h1>Exercise: count prime numbers</h1> 286 <div class="columns"> 287 <ul> 288 <li>Write a web app that takes a single integer n as input 289 and prints <strong>the number of prime numberss less than n</strong> when 290 the user presses a button.</li> 291 <li>Solution: <a href=./examples/3-primes>examples/3-primes</a></li> 292 </ul> 293 <img src="./images/meme2.jpg" style="width: 70%;"> 294 </div> 295 </div> 296 297 <div class="slide" tabindex="-1"> 298 <h1>Performance benchmark</h1> 299 <table id="bench"> 300 <tr> 301 <th></th> 302 <th>Firefox <br>WASM (-O3)</th><th>Firefox <br>JS</th> 303 <th>Chromium <br>WASM (-O3)</th><th>Chromium <br>JS</th> 304 </tr> 305 <tr> 306 <td>1e7 Primes (iterative)</td> 307 <td>4.5s</td><td>4.4s</td> 308 <td>4.7s</td><td>4.6s</td> 309 <tr> 310 <tr> 311 <td>1e7 Primes (sieve)</td> 312 <td>0.76s</td><td>0.82s</td> 313 <td>0.92s</td><td>0.80s</td> 314 <tr> 315 <tr> 316 <td>Matrix multiplication</td> 317 <td>0.81s</td><td>5.3s</td> 318 <td>1.5s</td><td>4.6s</td> 319 <tr> 320 </table> 321 <img src="./images/fast.jpg" style="width: 30%; margin: auto;"> 322 </div> 323 324 <div class="slide" tabindex="-1"> 325 <h1>More exercises</h1> 326 327 <p>See <a href="https://github.com/sebastianotronto/emscripten-tutorial"> 328 github.com/sebastianotronto/emscripten-tutorial</a></p> 329 330 <div class="columns"> 331 <ul> 332 <li><strong>Fix UI freezing:</strong> very large numbers in example 3 333 can block the UI. Can you fix this?</li> 334 <li><strong>More faster:</strong> use multi-threading 335 (<a href="https://en.wikipedia.org/wiki/Pthreads">pthreads</a> or 336 <a href="https://en.cppreference.com/w/cpp/thread/thread.html">std::thread</a>) to make our examples faster. Watch out for 337 <a href="https://spectreattack.com/">Spectre</a>!</li> 338 <li><strong>Show progress:</strong> using callback functions, make our 339 long-running examples show their progress in the web page.</li> 340 </ul> 341 342 <img src="./images/pencil.jpg" style="width: 60%; margin: auto;"> 343 344 </div> 345 </div> 346 347 348 <div class="slide titlepage" tabindex="-1" 349 style="background-image: url('images/beer.jpg'); 350 background-position: center; 351 background-repeat: no-repeat; 352 background-size: 80%; 353 background-color: rgba(255, 255, 255, 0.65); 354 background-blend-mode: overlay;"> 355 <p></p> 356 <p><span class="title">Drinks!</span></p> 357 <p></p> 358 </div> 359 360 <script> 361 // The list of all slides of the presentation. 362 const slides = document.querySelectorAll(".slide"); 363 364 // Navigation keys. 365 const keysNext = ["ArrowRight", "ArrowDown", " "]; 366 const keysPrev = ["ArrowLeft", "ArrowUp"]; 367 368 // Function to move to a given slide. 369 // This also focuses the slide, so any key press will be 370 // handled by the correct slide's event handler. 371 function goto(slide) { 372 slide.focus(); 373 slide.scrollIntoView({ 374 behavior: "instant", 375 block: "start" 376 }); 377 } 378 379 // Handle key press events. 380 function onkeydown(i, e) { 381 if (keysNext.includes(e.key) && i+1 < slides.length) { 382 goto(slides[i+1]); 383 } 384 if (keysPrev.includes(e.key) && i > 0) { 385 goto(slides[i-1]); 386 } 387 } 388 389 // Disabled for these slides, it messes with interactive elements; 390 // see also the part that adds event listeners below. 391 // 392 // Handle click or tap events. 393 // Tapping on the right half of the screen scrolls forwards, 394 // tapping on the left half scrolls backwards. 395 //function onclick(i, e) { 396 // const w = slides[i].offsetWidth; 397 // const x = e.clientX; 398 // 399 // if (x > w/2 && i+1 < slides.length) { 400 // goto(slides[i+1]); 401 // } 402 // if (x < w/2 && i > 0) { 403 // goto(slides[i-1]); 404 // } 405 //} 406 407 // Disable default action of the navigation keys (e.g. scrolling). 408 document.addEventListener("keydown", function(e) { 409 if (keysNext.includes(e.key) || keysPrev.includes(e.key)) { 410 e.preventDefault(); 411 } 412 }); 413 414 // Function to add a footer to every slide. 415 function slideFooter() { 416 const start = "<div class=\"footer\"><table class=\"footer-table\"><tr>"; 417 const title = "WebAssembly and Emscripten" 418 const link = "<a href=https://tronto.net/talks/wasm>tronto.net/talks/wasm</a>"; 419 const end = "</tr></table></div>"; 420 const content = 421 "<td class=\"footer-title\">" + title + "</td>" + 422 "<td class=\"footer-link\">" + link + "</td>"; 423 424 return start + content + end; 425 } 426 427 // Add slide footers and event handlers. 428 for (let i = 0; i < slides.length; i++) { 429 slides[i].innerHTML += slideFooter(); 430 slides[i].addEventListener("keydown", e => onkeydown(i, e)); 431 //slides[i].addEventListener("click", e => onclick(i, e)); 432 } 433 434 // Focus and scroll into view the first slide. 435 goto(slides[0]); 436 437 // Call highlight.js 438 hljs.highlightAll(); 439 </script> 440 441 <!-- Script for first example slide --> 442 <script> 443 var aInput = document.getElementById("aInput"); 444 var bInput = document.getElementById("bInput"); 445 var button = document.getElementById("resultButton"); 446 var resultText = document.getElementById("resultText"); 447 448 button.addEventListener("click", () => { 449 var a = Number(aInput.value); 450 var b = Number(bInput.value); 451 resultText.innerText = a + b; 452 }); 453 </script> 454 455 </body> 456 </html>