Parallel.js

Florian Rappl

Parallel.js

geht nicht, gibts nicht!

HTML 5

Florian Rappl

Writer and consultant

  • Microsoft C# MVP
  • Active contributions to open-source projects
  • Articles for CodeProject, SitePoint, tuts+, ...

Languages and technologies

  • C#, JavaScript, and C/C++
  • Full web stack (client and server)
  • High Performance and Embedded Computing, IoT

Why this talk?

GitHub Parallel.js SitePoint Parallel.js article

Agenda

  1. Web Worker
  2. Parallel.js
  3. Demos, demos, demos
  4. SIMD.js
Worker

Introduction

  • What makes JavaScript suitable for parallelism?
    • Browsing contexts
    • Implicit synchronization
    • Explicit spawning

Secret Ingredient: The Event Loop

JavaScript Event Loop

A Classic Problem of Parallel Computing

Sequential implementation

Naive parallel implementation

Possible Solutions

Lock critical regions

Global synchronization

The JS Way: Messages API

  • Communication over messages
  • Direct send, indirect receive (event)
  • Mediated over reactor, i.e., thread-safe
  • Avoids classic race conditions
  • Drawback: Messages are always strings
  • Need to serialize arguments (JSON)

Messages API Examples

  • Receiving from some window:
    window.addEventListener('message', function (ev) {
    	ev.source.postMessage('Howdy Cowboy!', ev.origin);
    }, false);
    					
  • Sending to a created window:
    var popup = window.open(/* ... */);
    popup.postMessage('Hello World!', '*');
    					

Back to the Problem

Worker Types

  • Dedicated workers exposed as Worker
  • Shared workers via SharedWorker
  • Service workers come as ServiceWorker

Dedicated Worker Example

var fs = (function () { 
	postMessage('Hello World');
}).toString(); 
var blob = new Blob(
   [fs.substr(13, fs.length - 14)],
   { type: 'text/javascript' }
);
var url = window.URL.createObjectURL(blob);
var worker = new Worker(url);
worker.addEventListener('message', function (ev) {
	console.log(ev.data);
}, false);
			
Parallel

What is Parallel.js?

  • Elegant worker wrapper
  • Easy to utilize
  • Data-driven API (data first)
  • Uses of Promise to avoid callback hell

Essential API (1)

  • Creating a new parallel context
    var p1 = new Parallel('Hello World!');
    var p2 = new Parallel([1, 2, 3, 4, 5]);
    					
  • Spawning a new worker:
    p1.spawn(data => data.split('').reverse().join(''));
    					
  • Using the result:
    p2.spawn(data => data.length).then(data => console.log(data));
    					

Reductions

  • Helpers to avoid boilerplate
  • Parallel algorithms (scatter, gather, ...)
  • Everything is callback-based

Setup Workers

  • Each worker starts with a clean context
  • Include external functions
  • Include required libraries
  • Define auxiliary methods

Essential API (2)

  • Gather / scatter operations:
    var p1 = new Parallel([1, 2, 3, 4, 5]);
    p1.map(element => Math.exp(element * 0.1));
    var p2 = new Parallel(_.range(100));
    p2.reduce(elements => elements[0] + elements[1]));
    					
  • Defining the environment:
    var p = new Parallel([ /* ... */ ], {
    	env: { a: 10 }, envNamespace: 'parallel'
    });
    					
  • Including helpers:
    function factorial (n) { /* ... */ }
    p.require(factorial);
    					
Demos

→ 1 - Spawning Threads

→ 2 - Distribute Work

→ 3 - Providing Functionality

→ 4 - Show me more!

Vectorization

What is SIMD.js?

  • Vectorization in JavaScript!
  • Needs to be part of the runtime
  • Require special datatypes, e.g.,
    • SIMD.Float32x4
    • SIMD.Float64x2
    • SIMD.Uint32x4
    • SIMD.Int16x8
  • Use with special operations
SIMD.js Datatypes

Vectorization Examples

var a = SIMD.Float32x4(1, 2, 3, 4);
var b = SIMD.Float32x4(5, 6, 7, 8);
var sum = SIMD.Float32x4.add(a, b);
var reversed = SIMD.Float32x4.swizzle(b, 3, 2, 1, 0);
var difference = SIMD.Float32x4.sub(reversed, a);
var mixed = SIMD.Float32x4.shuffle(a, b, 0, 2, 5, 7);
			

→ 5 - SIMD.js

Thanks for your attention!

  • Feel free to contact me