sebastiano.tronto.net

Source files and build scripts for my personal website
git clone https://git.tronto.net/sebastiano.tronto.net
Download | Log | Files | Refs | README

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>