MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

This is an experimental technology, part of the ECMAScript 2016 (ES7) proposal.
Because this technology's specification has not stabilized, check the compatibility table for usage in various browsers. Also note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.

SIMD ("seem-dee"と読みます) は Single Instruction/Multiple Data の略で、フリンの分類によるコンピュータ・アーキテクチャの一種です。 SIMD演算では、単一の操作を複数のデータに同時に適用することでデータレベルでの並列化ができ、それゆえに、例えば3Dグラフィクスや動画像処理、物理シミュレーションや暗号化といった、様々な分野においてパフォーマンス向上を達成します。

このページとサプページは、 SIMD API のリファレンスドキュメントです。より一般的な JavaScript での SIMD に触れた記事については、SIMD タイプ もご覧ください。

説明

JavaScriptのSIMD APIは、幾つかのデータ型と命令から成ります。ブラウザはハードウェアに最適化されたAPIを提供します。現在は特にARMv7 platforms with NEONx86 platforms with SSEに最適化された設計となっています。

SIMD APIの型はSIMDモジュール内で提供されます。多くのグローバルオブジェクトがコンストラクタであるのとは違い、SIMDはコンストラクタではありません。そのため、new演算子を使うこと、関数として呼び出すことはできません。全てのプロパティやメソッドは静的メンバとして提供されます(つまり、Math オブジェクトと同様です)。

概要

SIMDの値は複数のレーンを持っています。例として、(x, y, z, w) という長さ4のベクトルを考えてみましょう。4つの値それぞれに同一の操作を1回ずつ、計4回操作を行う代わりに、SIMDでは4つのレーンに同時に操作を行えます。これは少ない演算回数を要求する為、スカラー演算(SISD)と比べて処理の高速化やエネルギー消費量削減などのメリットがあります。ただし、SIMD演算では異なる方法のデータ処理を同時に行うことはできません。次の図では、「加算」という同一の操作を行っているため、SIMDが適用できます。

SISD SIMD

図1,2: SISDとSIMDの比較

単純な加算の例

図2の様子をJavaScriptで書くと次のようになります。

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]

データ型

SIMDのデータ型は全てイミュータブルであり、一度作成すると直接内部の値を変えることはできません。代わりに、新しいSIMDのデータ型のオブジェクトを作ることはできます。次の図は128bit SIMD レジスタにおけるSIMDデータ型の一覧です。現在、JavaScript の SIMD APIでは12の異なるデータ型が提供されており、レーン数は2, 4, 8または16のいずれかとなります。

Lanes per type in a 128-bit SIMD register

図3: 128bit SIMD レジスタにおけるデータ型毎のレーン数

SIMD ブーリアン型

SIMD.Bool8x16
128bitを16個のレーンに分割し、各レーンは論理値を持ちます。
SIMD.Bool16x8
128bitを8個のレーンに分割し、各レーンは論理値を持ちます。
SIMD.Bool32x4
128bitを4個のレーンに分割し、各レーンは論理値を持ちます。
SIMD.Bool64x2
128bitを2個のレーンに分割し、各レーンは論理値を持ちます。

SIMD 符号つき整数型

SIMD.int8x16
128bitを16個のレーンに分割し、各レーンは8bitの符号付き整数値を持ちます
SIMD.int16x8
128bitを8個のレーンに分割し、各レーンは16bitの符号付き整数値を持ちます
SIMD.int32x4
128bitを4個のレーンに分割し、各レーンは32bitの符号付き整数値を持ちます
SIMD.float32x4
128bitを4個のレーンに分割し、各レーンは32bitの単精度浮動小数値を持ちます
SIMD.float64x2
128bitを2個のレーンに分割し、各レーンは64bitの倍精度浮動小数値を持ちます

SIMD 符号なし整数型

SIMD.Uint8x16
128-bits divided into 16 lanes storing 8-bit unsigned integer values.
SIMD.Uint16x8
128-bits divided into 8 lanes storing 16-bit unsigned integer values.
SIMD.Uint32x4
128-bits divided into 4 lanes storing 32-bit unsigned integer values.

SIMD 浮動小数型

SIMD.Float32x4
128-bits divided into 4 lanes storing single precision floating point values.
SIMD.Float64x2
128-bits divided into 2 lanes storing double precision floating point values.

コンストラクタ

単純なコンストラクタ (SIMD.Int32x4(1,2,3,4)など)に加え, SIMD APIでは次のようなコンストラクタも提供しています。

You can also convert from one SIMD data type to another.

SIMD.%type%.splat()
指定した値で初期化されたSIMDデータを作成します

Note: SIMD types don't work with new, as SIMD values are no "boxed" objects (comparable to String(s) vs. new String(s), which creates a String object).

var v = new SIMD.Float32x4(0,1,2,3);
// TypeError: SIMD.Float32x4 is not a constructor

Instead, you just write:

var v = SIMD.Float32x4(0,1,2,3);

演算

実際に SIMD 型を動かすには、 SIMDデータ型上で動く演算が必要となります。

Note: Not all SIMD operations are available on all SIMD types, see the individual reference pages for details and availability.

SIMDデータ型の確認

SIMD.%type%.check()
もし引数がSIMDデータならば、引数自身を返します。それ以外の場合、TypeErrorを投げます。

レーンへの操作

SIMD.%type%.extractLane()
指定されたレーンの値を返します。
SIMD.%type%.replaceLane()
指定されたレーンの値を指定された値で置き換えた、新しいSIMDデータを返します。

TypedArrayとの相互変換

SIMD.%type%.load()
SIMD.%type%.load1()
SIMD.%type%.load2()
SIMD.%type%.load3()
typed array から新しいSIMDデータを作ります。
SIMD.%type%.store()
SIMD.%type%.store1()
SIMD.%type%.store2()
SIMD.%type%.store3()
SIMDデータの値をtyped arrayにセットします。

算術演算

SIMD.%type%.abs()
各レーンの値の絶対値からなる新しいSIMDデータを返します(a + b)。
SIMD.%type%.add()
2つのSIMD型の各レーンの和(a + b)からなる新しいSIMDデータと、オーバーフロー時の飽和動作を返します。
SIMD.%type%.div()
2つのSIMD型の各レーンの商からなる新しいSIMDデータを返します(a / b)。
SIMD.%type%.mul()
2つのSIMD型の各レーンの積からなる新しいSIMDデータを返します(a * b)。
SIMD.%type%.neg()
各レーンの正負を反転させた新しいSIMDデータを返します。
SIMD.%type%.reciprocalApproximation()
各レーンの逆数の近似値からなる新しいSIMDデータを返します。
SIMD.%type%.reciprocalSqrtApproximation()
各レーンの平方根の逆数の近似値からなる新しいSIMDデータを返します。
SIMD.%type%.sub()
2つのSIMD型の各レーンの差からなる新しいSIMDデータを返します (a - b)。
SIMD.%type%.subSaturate()
2つのSIMD型の各レーンの差(a - b)からなる新しいSIMDデータと、オーバーフロー時の飽和動作を返します。
SIMD.%type%.sqrt()
各レーンの平方根からなる新しいSIMDデータを返します。

シャッフルと再順序付け

SIMD.%type%.shuffle()
2つのSIMD型のSIMDデータをシャッフルした新しいSIMDデータを返します。
SIMD.%type%.swizzle()
SIMDデータを再順序付けした新しいSIMDデータを返します。

最大値・最小値

 
SIMD.%type%.max()
2つのSIMD型の各レーンの最大値からなる新しいSIMDデータを返します。
SIMD.%type%.maxNum()
2つのSIMD型の各レーンの最大値からなる新しいSIMDデータを返します。NaNが含まれる場合、NaNよりも数値が優先されます。
SIMD.%type%.min()
2つのSIMD型の各レーンの最小値からなる新しいSIMDデータを返します。
SIMD.%type%.minNum()
2つのSIMD型の各レーンの最小値からなる新しいSIMDデータを返します。NaNが含まれる場合、NaNよりも数値が優先されます。

選択

SIMD.%type%.select()
セレクタマスクに基づいて2つのSIMD型からデータを選択した、新しいSIMDデータを返します。

比較

SIMD.%type%.equal()
2つのSIMD型の各レーンの値a, bについてa == bを評価し、その結果をセレクタマスクとして返します。
SIMD.%type%.notEqual()
2つのSIMD型の各レーンの値a, bについてa != bを評価し、その結果をセレクタマスクとして返します。
SIMD.%type%.lessThan()
2つのSIMD型の各レーンの値a, bについてa < bを評価し、その結果をセレクタマスクとして返します。
SIMD.%type%.lessThanOrEqual()
2つのSIMD型の各レーンの値a, bについてa <= bを評価し、その結果をセレクタマスクとして返します。
SIMD.%type%.greaterThan()
2つのSIMD型の各レーンの値a, bについてa > bを評価し、その結果をセレクタマスクとして返します。
SIMD.%type%.greaterThanOrEqual()
2つのSIMD型の各レーンの値a, bについてa >= bを評価し、その結果をセレクタマスクとして返します。

論理演算

SIMD.%type%.and()
2つのSIMD型の各レーンの値について、その論理積からなる新しいSIMDデータを返します
SIMD.%type%.or()
2つのSIMD型の各レーンの値について、その論理和からなる新しいSIMDデータを返します
SIMD.%type%.xor()
2つのSIMD型の各レーンの値について、その排他的論理和からなる新しいSIMDデータを返します
SIMD.%type%.not()
SIMD型の各レーンの値について、その否定からなる新しいSIMDデータを返します

ビットシフト

SIMD.%type%.shiftLeftByScalar()
SIMD型の各レーンの値について、指定された桁数だけ左シフトした値からなる新しいSIMDデータを返します (a << bits).
SIMD.%type%.shiftRightArithmeticByScalar()
SIMD型の各レーンの値について、指定された桁数だけ右シフトした値からなる新しいSIMDデータを返します。符号は維持されます(a >> bと同様)
SIMD.%type%.shiftRightLogicalByScalar()
SIMD型の各レーンの値について、指定された桁数だけ右シフトした値からなる新しいSIMDデータを返します。空いた上位bitは0で埋められます(a >>> bと同様)

ブーリアン演算

SIMD.%BooleanType%.allTrue()
Checks if all lanes hold a true value.
SIMD.%BooleanType%.anyTrue()
Checks if any of the lanes hold a true value.

データの変換

SIMD.%type%.fromFloat32x4()
float32x4からfloat変換された新しいSIMDデータ型を生成します。
SIMD.%type%.fromFloat32x4Bits()
float32x4からビット単位にコピーされた新しいSIMDデータ型を生成します。
SIMD.%type%.fromFloat64x2()
float64x2からfloat変換された新しいSIMDデータ型を生成します。
SIMD.%type%.fromFloat64x2Bits()
float64x2からビット単位にコピーされた新しいSIMDデータ型を生成します。
SIMD.%type%.fromInt32x4()
int32x4からfloat変換された新しいSIMDデータ型を生成します。
SIMD.%type%.fromInt32x4Bits()
int32x4からビット単位にコピーされた新しいSIMDデータ型を生成します。
SIMD.%type%.fromInt16x8Bits()
int16x8からfloat変換された新しいSIMDデータ型を生成します。
SIMD.%type%.fromInt8x16Bits()
int16x8からビット単位にコピーされた新しいSIMDデータ型を生成します。

 

SIMD プロトタイプ

以下のメソッドとプロバティは SIMD.%type%.prototype によってインストールされます。

SIMD.%type%.prototype.constructor
SIMD オブジェクトのプロトタイプを生成する関数を指定します。
SIMD.%type%.prototype.toLocaleString()
SIMD タイプとその要素を表現するローカライズされた文字列を返します。Object.prototype.toLocaleString() メソッドをオーバーライドします。
SIMD.%type%.prototype.toString()
SIMD タイプとその要素を表現する文字列を返します。 Object.prototype.toString() メソッドをオーバーライドします。
SIMD.%type%.prototype.valueOf()
SIMD オブジェクトの元の値を返します。
SIMD.%type%.prototype.toSource()
オブジェクトのソースコードを表現する文字列を返します。Object.prototype.toSource() メソッドをオーバーライドします。

Polyfill

A Polyfill implementation based on typed arrays, is available at the ecmascript_simd GitHub repository.

Specifications

Specification Status Comment
SIMD
SIMD の定義
ドラフト Initial definition.

Browser compatibility

Feature Chrome Firefox (Gecko) Edge Internet Explorer Opera Safari
Basic support 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Float32x4 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Float64x2 未サポート Nightly build 未サポート 未サポート 未サポート 未サポート
SIMD.Int8x16 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Int16x8 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Int32x4 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Uint8x16 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Uint16x8 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Uint32x4 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool8x16 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool16x8 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool32x4 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool64x2 未サポート Nightly build 未サポート 未サポート 未サポート 未サポート
Feature Android Chrome for Android Firefox Mobile (Gecko) Edge IE Mobile Opera Mobile Safari Mobile
Basic support 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Float32x4 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Float64x2 未サポート 未サポート Nightly build 未サポート 未サポート 未サポート 未サポート
SIMD.Int8x16 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Int16x8 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Int32x4 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Uint8x16 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Uint16x8 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Uint32x4 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool8x16 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool16x8 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool32x4 未サポート 未サポート Nightly build Nightly build 未サポート 未サポート 未サポート
SIMD.Bool64x2 未サポート 未サポート Nightly build 未サポート 未サポート 未サポート 未サポート

Status notes

参照

ドキュメントのタグと貢献者

 このページの貢献者: chikoski, ykzts, Uemmra3, lv7777, Kikurage, fscholz
 最終更新者: chikoski,