Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Revision 805011 of SIMD types

  • Revision slug: Web/JavaScript/SIMD_types
  • Revision title: SIMD types
  • Revision id: 805011
  • Created:
  • Creator: fscholz
  • Is current revision? No
  • Comment more WIP
Tags: 

Revision Content

{{JSSidebar("Advanced")}}

The experimental JavaScript SIMD API introduces vector objects that utilize SIMD/SSE instructions on supporting CPUs; {{Glossary("SIMD")}} is short for Single Instruction/Multiple Data. SIMD operations are methods that process multiple data with a single instruction. In contrary, scalar operations ({{Glossary("SISD")}}) process only one individual data with a single instruction.

Processing a data set with a single instruction can bring a big performance win to your application. How much depends on the size of the data set (or vector, or packed data) among other things. Thus, SIMD operations are widely used for 3D graphics and audio/video processing, physics simulations, cryptography, and other domains.

A downside of SIMD, and this is why algorithms need to be designed for SIMD, is that the packed data set can not be processed differently while your algorithm often needs to process different data differently. We will learn later in this article how we can work with masks, for example, to address this problem.

Shared memory or thread level parallelism allow different parallel paths on multiple data and with multiple instructions (MIMD). Parallel programming can be simpler with these techniques, but these concepts can also be used together with SIMD. For example, you could image to have SIMD vectorization that is utilized in each thread of your program. This Mandelbrot demo, by Peter Jensen (Intel), demonstrates the performance gains of SIMD and Web Workers, for example.

SIMD in JavaScript

The JavaScript SIMD API consists of several new data types and operations allowing you to make use of SIMD instructions from JavaScript. Browsers provide highly optimized implementations of this API depending on the underlying hardware of the user. Currently, the JS SIMD API is especially modeled for ARMv7 platforms with NEON and x86 platforms with SSE.

Let's look at a SIMD data type, for example {{jsxref("float32x4", "SIMD.float32x4")}}. A SIMD vector consists of multiple data units, they are called lanes. A SIMD register for the current API is 128-bit wide. For a vector of length 4 (x4), there are 4 float32 types that fit in and the lanes are named x, y, z, and w. Now, instead of having to perform 4 separate operations on each of these lanes, SIMD allows you to perform the operation on all 4 lanes simultaneously.

In the following figure, there is only a single instruction (addition) and thus the data can be processed using SIMD:

SISD SIMD

Figures 1 and 2: SISD and SIMD compared.

The scalar / SSID code could like this (without any loop, just for illustration):

var a = [1, 2, 3, 4];
var b = [5, 6, 7, 8];
var c = [];

c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
c[2] = a[2] + b[2];
c[3] = a[3] + b[3];
c; // Array[6, 8, 10, 12]

Now using SIMD:

var a = SIMD.float32x4(1, 2, 3, 4);
var b = SIMD.float32x4(5, 6, 7, 8);
var c = SIMD.float32x4.add(a,b); // float32x4[6, 8, 10, 12]

This will add the values in the four lanes simultaneously and give you back a new SIMD float32 type with all lanes added.

As you can see in the three lines of SIMD code, a set of JavaScript functions lets you create the packaged data types and gives you access to the vectorized instructions (addition here). At the time of writing this article, there is no operator overloading (i.e. a `+` sign) implemented to ease the writing of SIMD code like this. However, the JavaScript SIMD API is not yet finished and there are plans to include operator overloading in one of the next drafts. You can follow the specification development in the ecmascript_simd GitHub repository.

Re-aligning data to suit SIMD vectors

Oftentimes there are arrays that serve as input data for SIMD vectors. However, the structure of these arrays might not always be suited for SIMD operations. Let's take a look at RGBA color data in images, for example.

With the help of the {{domxref("CanvasRenderingContext2D.getImageData()")}} method in a canvas and the {{domxref("ImageData.data")}} property you can get back the underlying pixel data as a one-dimensional array containing the image data in the RGBA order, with integer values between 0 and 255 (included):

[R, G, B, A, R, G, B, A, R, G, B, A, ...]

If we now want to process this image, for example calculating the perceived luminance/grayscale with the formula Y = 0.299r + 0.587g + 0.114b, we need to restructure the data for SIMD. The idea is to process the different weights for r, g, and b in a SIMD suitable format with one instruction per color data. This could look like this:

[R, R, R, R, R, R, ...] * 0.299 +
[G, G, G, G, G, G, ...] * 0.587 +
[B, B, B, B, B, B, ...] * 0.114b =
[Y, Y, Y, Y, Y, Y, ...]

Parallelizing conditional branches

tbd

SIMD algorithms and use cases

The following algorithms and use cases can benefit greatly from SIMD operations:

In general, data that can be processed with the same set of instruction can highly benefit from SIMD.

See also

  • {{jsxref("SIMD")}} reference pages, listing all available SIMD types and operations.

Revision Source

<div>{{JSSidebar("Advanced")}}</div>

<p>The experimental JavaScript SIMD API introduces vector objects that utilize SIMD/SSE instructions on supporting CPUs; {{Glossary("SIMD")}} is short for Single Instruction/Multiple Data.<em> SIMD operations</em> are methods that process multiple data with a single instruction. In contrary, <em>scalar operations</em> ({{Glossary("SISD")}}) process only one individual data with a single instruction.</p>

<p>Processing a data set with a single instruction can bring a big performance win to your application. How much depends on the size of the <em>data set</em> (or <em>vector</em>, or <em>packed data</em>) among other things. Thus, SIMD operations are widely used for 3D graphics and audio/video processing, physics simulations, cryptography, and other domains.</p>

<p>A downside of SIMD, and this is why algorithms need to be designed for SIMD, is that the packed data set can not be processed differently while your algorithm often needs to process different data differently. We will learn later in this article how we can work with masks, for example, to address this problem.</p>

<p>Shared memory or thread level parallelism allow different parallel paths on multiple data and with multiple instructions (MIMD). Parallel programming can be simpler with these techniques, but these concepts can also be used together with SIMD. For example, you could image to have SIMD vectorization that is utilized in each thread of your program. This <a href="https://peterjensen.github.io/mandelbrot/js/mandelbrot-ww-asm.html">Mandelbrot demo</a>, by Peter Jensen (Intel), demonstrates the performance gains of SIMD and <a href="/en-US/docs/Web/API/Web_Workers_API">Web Workers</a>, for example.</p>

<h2 id="SIMD_in_JavaScript">SIMD in JavaScript</h2>

<p>The<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SIMD"> JavaScript SIMD API</a> consists of several new <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SIMD#Data_types">data types</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SIMD#Operations">operations</a> allowing you to make use of SIMD instructions from JavaScript. Browsers provide highly optimized implementations of this API depending on the underlying hardware of the user. Currently, the JS SIMD API is especially modeled for <a class="external external-icon" href="https://en.wikipedia.org/wiki/ARM_architecture#Advanced_SIMD_%28NEON%29">ARMv7 platforms with NEON</a> and <a class="external external-icon" href="https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions">x86 platforms with SSE</a>.</p>

<p>Let's look at a SIMD data type, for example {{jsxref("float32x4", "SIMD.float32x4")}}. A SIMD vector consists of multiple data units, they are called <em>lanes</em>. A SIMD register for the current API is 128-bit wide. For a vector of length 4 (<code>x4</code>), there are 4 <code>float32</code> types that fit in and the lanes are named <code>x</code>, <code>y</code>, <code>z</code>, and <code>w</code>. Now, instead of having to perform 4 separate operations on each of these lanes, SIMD allows you to perform the operation on all 4 lanes simultaneously.</p>

<p>In the following figure, there is only a single instruction (addition) and thus the data can be processed using SIMD:</p>

<div><img alt="SISD" src="https://mdn.mozillademos.org/files/10509/SISD.png" style="width:337px" /> <img alt="SIMD" src="https://mdn.mozillademos.org/files/10507/SIMD.png" style="width:337px" /></div>

<p>Figures 1 and 2: SISD and SIMD compared.</p>

<p>The scalar / SSID code could like this (without any loop, just for illustration):</p>

<pre class="brush: js">
var a = [1, 2, 3, 4];
var b = [5, 6, 7, 8];
var c = [];

c[0] = a[0] + b[0];
c[1] = a[1] + b[1];
c[2] = a[2] + b[2];
c[3] = a[3] + b[3];
c; // Array[6, 8, 10, 12]
</pre>

<p>Now using SIMD:</p>

<pre class="brush: js">
var a = SIMD.float32x4(1, 2, 3, 4);
var b = SIMD.float32x4(5, 6, 7, 8);
var c = SIMD.float32x4.add(a,b); // float32x4[6, 8, 10, 12]</pre>

<p>This will add the values in the four lanes simultaneously and give you back a new SIMD <code>float32</code> type with all lanes added.</p>

<p>As you can see in the three lines of SIMD code, a set of JavaScript functions lets you create the packaged data types and gives you access to the vectorized instructions (addition here). At the time of writing this article, there is no operator overloading (i.e. a `+` sign) implemented to ease the writing of SIMD code like this. However, the JavaScript SIMD API is not yet finished and there are plans to include operator overloading in one of the next drafts. You can follow the specification development in the <a href="https://github.com/johnmccutchan/ecmascript_simd">ecmascript_simd GitHub repository</a>.</p>

<h2 id="Re-aligning_data_to_SIMD_vectors">Re-aligning data to suit SIMD vectors</h2>

<p>Oftentimes there are arrays that serve as input data for SIMD vectors. However, the structure of these arrays might not always be suited for SIMD operations. Let's take a look at RGBA color data in images, for example.</p>

<p>With the help of the {{domxref("CanvasRenderingContext2D.getImageData()")}} method in a canvas and the {{domxref("ImageData.data")}} property you can get back the underlying pixel data as a one-dimensional array containing the image data in the RGBA order, with integer values between <code>0</code> and <code>255</code> (included):</p>

<p><code>[R, G, B, A, R, G, B, A, R, G, B, A, ...]</code></p>

<p>If we now want to process this image, for example calculating the <a href="https://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale">perceived luminance/grayscale</a> with the formula <code>Y = 0.299r + 0.587g + 0.114b</code>, we need to restructure the data for SIMD. The idea is to process the different weights for r, g, and b in a SIMD suitable format with one instruction per color data. This could look like this:</p>

<p><code>[R, R, R, R, R, R, ...] * 0.299 +<br />
 [G, G, G, G, G, G, ...] * 0.587 +<br />
 [B, B, B, B, B, B, ...] * 0.114b =<br />
 [Y, Y, Y, Y, Y, Y, ...]</code></p>

<h2 id="Parallelizing_conditional_branches">Parallelizing conditional branches</h2>

<p>tbd</p>

<h2>SIMD algorithms and use cases</h2>

<p>The following algorithms and use cases can benefit greatly from SIMD operations:</p>

<ul>
 <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SIMD#Data_conversions">Converting data to another type</a></li>
 <li>Algorithms: <a href="https://en.wikipedia.org/wiki/Sum_of_absolute_differences">Sum of absolute differences (SAD)</a>, <a href="https://en.wikipedia.org/wiki/Discrete_cosine_transform">Discrete cosine transform (DCT)</a></li>
 <li>Graphics: Rasterization, pixel shading, ray tracing.</li>
 <li>Mathematics: Matrix operations, linear algebra.</li>
</ul>

<p>In general, data that can be processed with the same set of instruction can highly benefit from SIMD.</p>

<h2 id="See_also">See also</h2>

<ul>
 <li>{{jsxref("SIMD")}} reference pages, listing all available SIMD types and operations.</li>
</ul>
Revert to this revision