Browser

Microsoft Edge(Project Spartan, Internet Explorer) 、ブラウザ周辺、Web フロントエンド開発、UI、など

Microsoft Edge まとめページ

Microsoft Edge の機能を調べてみた - SIMD.js 編

 参照元

developer.mozilla.org

 

SIMD.js は Intel, Google, Mozilla が開発、他も取り組み始めている模様で、知る限りでは Dart から SIMD を操作するやつが祖先のような気がします。(違ってたらごめんなさい)

SIMD.js は ECMAScript 2016 で計画されており、現状では通常の状態の Edge で SIMD.js は動作しません。
アドレスバーに about:flags を入力して "asm.js を有効にする" にチェックし Edge を再起動しましょう。

f:id:x67x6fx74x6f:20150722164813p:plain

また、ここ最近でつくられたものですので、今後大幅な仕様変更が行われる可能性もあり、注意が必要です。

 

SIMD とは?

Single Instruction Multiple Data の略で、所謂、ベクトル演算(ベクトル処理)
1つの命令で同時に複数のデータに適応して並列処理する方式です。
JavaScript など通常の処理では SISD(Single Instruction Single Data)という1つのデータに対して1つの命令を処理する形をとっています。

チップによって名称や機能が異なり、たぶんブラウザがメインで使うのはこの2つ。

現在販売されているものでは問題がないと思われますが古いモバイル端末では NEON を使うことができません。


SIMD の使い道

複数のデータ群(レーン)を1度に処理できるため画像処理、音の処理、3DCG などに使われます。

 

概要

SIMD.js は複数の値を保持するレーンというものがあります。
JavaScript で4つ値を持つの行列を足すには4回処理する必要がありますが、SIMD の場合1回で処理することができます。

f:id:x67x6fx74x6f:20150722165047p:plain

 

仕様では 128 bit SIMD レジスタとなっており、5つの型と2~16個のまとめたレーンをつくることができますが、
Edge で使用できるものは Int32x4、Float32x4、Float64x2 です 

f:id:x67x6fx74x6f:20150722165112p:plain

SIMD.Int32x4 128 Bit を4分割した 32 Bit の int 型の値を4つもつレーン
SIMD.Float32x4 128 Bit を4分割した 32 Bit の float 型の値を4つもつレーン
SIMD.Float64x2 128 Bit を2分割した 64 Bit の float 型の値を2つもつレーン

 

サンプルコード

 

注意点

以下3つ。

  • new 演算子は使えませんので SIMD.Int32x4(1,2,3,0) などの前に new をつけるとエラーになります。
  • 数値の演算ですので文字列関連の処理はできません。
  • SIMD 命令すべてが使えるわけではありません。

 

使用できるメソッド

MDN とほぼ同じで日本語化されているため、あるものはリンクでのご紹介。
%type% は現状の Edge では Int32x4、Float32x4、Float64x2 のいずれかが入ります。


SIMD.%type%.zero()
レーンの値すべてに0の値を入れる

 

SIMD.%type%.splat()
レーンの値すべてを指定された値で設定する

SIMD.%type%.bool()
レーンの各値に bool 値を設定する。
現状の Edge は Int32x4 以外でエラーになる。
(bool なので float 使う必要がない)

算術演算

SIMD.%type%.abs() 絶対値
SIMD.%type%.add() 加算
SIMD.%type%.div() 除算
SIMD.%type%.mul() 乗算
SIMD.%type%.neg() 符号反転
SIMD.%type%.sub() 減算
SIMD.%type%.sqrt() 平方根

リンク切れ
SIMD.%type%.reciprocal() 1/x SIMD 版。端数が出るので Float のみ
SIMD.%type%.reciprocalSqrt() Math.sqrt(1/x) の SIMD 版。端数が出るので Float のみ


シャッフル

SIMD.%type%.shuffle() 

【検証できず】レーンの値を指定し、キーとなる数字で並べ替えたレーンをつくる。
恐らく Firefox の Swizzle と同じ動きをするはず。


SIMD.%type%.shuffleMix()
【検証できず】 2つのレーンの値を指定し、キーとなる数字で並べ替えたレーンをつくる。
恐らく Firefox の Shuffle と同じ動きをするはず。

 

現状 shuffle と shuffleMix 正常なふるまいをしない。
自分の書き方が悪いのか、バグなのか不明だが  2 つ目で実行が止まってしまっているような気がしている。

 

最小値・最大値、クランプ

SIMD.%type%.max()
2つのレーンの各値を比較して最大値を入れたレーンをつくる


SIMD.%type%.min()

2つのレーンの各値を比較して最小値を入れたレーンをつくる

 

SIMD.%type%.clamp()
レーンの値を上限と下限の値に収めたレーンをつくる


選択

SIMD.%type%.select()
選択マスク用のレーンをつくり2つレーンの値のどちらかを選択する

 

比較

2つのレーンの値を比較し選択マスクを返す

SIMD.%type%.equal() a == b
SIMD.%type%.notEqual() a == b
SIMD.%type%.lessThan() a < b
SIMD.%type%.lessThanOrEqual() a <= b
SIMD.%type%.greaterThan() a > b
SIMD.%type%.greaterThanOrEqual() a >= b

 

論理値

2つのレーンの値を論理値として新しいレーンをつくる

SIMD.%type%.and() a & b
SIMD.%type%.or() a | b
SIMD.%type%.xor() a ^ b
SIMD.%type%.not() ~a

 

ビットシフト

ビットシフトを行いたいレーンに値分だけビットシフトする。Firefoxメソッド名が異なるので注意。
以下 a を 変更したいレーン、bits はビットシフトさせるビット数

SIMD.%type%.shiftLeft() a << bits
SIMD.%type%.shiftRightArithmetic() a >> bits
SIMD.%type%.shiftRightLogical() a >>> bits

 

データコンバート

他の方に変換する。
float32 から int32 へ変更する場合、値は切り捨ての模様。

SIMD.%type%.fromFloat32x4() int32x4 からの int32 float64 へ
SIMD.%type%.fromFloat32x4Bits() float32x4 からのビット単位のコピーへ
SIMD.%type%.fromFloat64x2() int64x2 からの int32 float32 へ
SIMD.%type%.fromFloat64x2Bits() float64x2 からのビット単位のコピーへ
SIMD.%type%.fromInt32x4() int32x4 からの float32 float64へ
SIMD.%type%.fromInt32x4Bits() int32x4 からのビット単位のコピーへ

 

Edge では現状使えないもの

SIMD.%type%.check()
SIMD.%type%.extractLane()
SIMD.%type%.replaceLane()
SIMD.%type%.load()
SIMD.%type%.store()
SIMD.%type%.maxNum()
SIMD.%type%.minNum()
SIMD.%type%.selectBits()
SIMD.%type%.fromInt16x8Bits()
SIMD.%type%.fromInt8x16Bits()

 

Polyfill

一応ある 

github.com

 

Windows 10 Moblie での対応

不明。
Lumia 1520 - Insider Preview Build 10166 で 試したところ、SIMD をオンにしない方が速くなった。
現状は最適化されていないのか、使えないのかは不明。

 

もっと知りたい。

英語ですが以下のサイトでどぞ


解説

SIMD in JavaScript | 01.org

 

仕様

SIMD.js specification v0.7.1

スポンサーリンク