Upload
hiroshi-kawada
View
3.499
Download
0
Embed Size (px)
Citation preview
HTML5とか勉強会#60 2015年09月29日
ECMAScript 7 - SIMD.js -
ふろしき
ふろしきです。先月にNTTを卒業して、某お絵かき系サービスの中の人になりました!!
東京Web Performance
html5j パフォーマンス部
(先月から)ピクシブ株式会社
自己紹介
「東京Webパフォーマンス」というイベント ピクシブのオフィスでひっそりとやっています
Webのパフォーマンスを改善する新しい機能を味見しまくる そんなイベントを不定期で開いています
for文の話をしよう突然だが…
普通のfor文による繰り返し、現場ではタブー感が
プログラミングの授業で習うfor文。 しかし世の言語は、これを使わせないようにする傾向にあります…なぜでしょう?
// 普通のfor文で各データに加算処理 for( var i=0; i<items.length ; i++ ) { items[i].add(count); }
正解… なんだけど??
// イテレーターで各データに加算処理 for( let item of items ) { item.add(count); }
なぜ、わざわざ こんな方法が…
パフォーマンスの問題を作ることがある!?
普通のfor文は、場合によってはパフォーマンスに問題を作ることがあります。 ループ文で処理する対象の特性にあった、対策が求められているのです
→
→
array[100000000]
繰り返し実装がむき出し
な処理
iterator
効率よい データストア 繰り返し
実装を隠蔽!!
データベースに接
続しようが
Generatorだ
ろうが
Immuta
ble.jsだろうが
な処理
何を使ったってい
い!!
API
ループはいつだって辛い 出来る限りループは効率化したい
SIMD というアプローチについて
例えば、データAとデータBを足した結果をだしたい時、データが2つならカンタン
データA データB+
しかしそれが、あるひとかたまりのデータ同士を足し算したいときは?
データA[0] データB[0]
データA[1] データB[1]
データA[2] データB[2]
データA[3] データB[3]
データA[4] データB[4]
+
+
+
+
+
ループが避けられない
当然、あの忌々しいループが必要になってしまいます。
データA[0]
データA[1]
データA[2]
データA[3]
データA[4]
1回目 加算命令
加算命令
加算命令
加算命令
加算命令
2回目
3回目
4回目
5回目
データB[0]
データB[1]
データB[2]
データB[3]
データB[4]
+
+
+
+
+
SIMDは複数データの加算を1命令で実行!!
SIMDでは、2つの大量データ同士の計算について、 通常はループでやるような処理を、一回の命令を実行できるようにしパフォーマンスを改善します
処理
Single Instruction
Multi Data
データA[0]
データA[1]
データA[2]
データA[3]
データA[4]
データB[0]
データB[1]
データB[2]
データB[3]
データB[4]
+
+
+
+
+
SIMD.js
SIMD.jsとは? -> part of ECMAScript7
SIMD.jsは、Intelらが中心となり仕様の策定を進めている JavaScriptでSIMDを扱う方法です。ECMAScript7に追加される予定です
→ Firefox
→ Edge
→ WebKit
←Intel(
2014年ご
ろ)
SIMDはCPUの機能、それをJSのAPIから触る
厳密には複数のデータ領域を一回の命令で操作できるというCPUの機能で、 JSでラップされたAPIを経由して扱います
データ[0]
データ[1]
データ[2]
データ[3]
データ[4]
メモリ
CPU
ユーザーランド
JavaScript による処理
ブラウザ
JavaScript API
CPU/メモリの 低級な仕組みに
バイパス
高級な APIによる ラップ
デメリット
あらかじめ準備された命令しか使えないため、やや柔軟性に欠けますが…、ハマれば高速です
データ[0]
データ[1]
データ[2]
データ[3]
データ[4]
メモリ
CPU
加算
減算
コピー
XORShift
なんでもできるわけじゃない… ループ文を置き換えれるなんて そんなカンタンなものじゃない!!
Get Start
データ領域の確保
メモリ上から、SIMDに適したデータ領域を確保し初期化します
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
hoge fuga
var hoge = SIMD.Float32x4(1.0,2.0,3.0,4.0); var fuga = SIMD.Float32x4(5.0,6.0,7.0,8.0);
計算する
計算して結果を格納します
var piyo = SIMD.Float32x4.add(hoge,fuga);
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
hoge fuga
6.0
8.0
10.0
12.0
piyo
出力する
結果を出力します
var foo = SIMD.Float32x4.extractLane(piyo,0);
6.0
8.0
10.0
12.0
piyo
6.0foo
出力する
結果を出力します
SIMD.Float32x4.extractLane(piyo,0);
6.0
8.0
10.0
12.0
piyo
6.0
DEMO
もう少しだけ実用的に
waifu2xのJS実装を改善
画像を拡大した時のあのギザギザ感をなくし シャープにみせるとあるアルゴリズムをSIMDで改善します!!
拡大 waifu2x
waifu2xのJS実装を改善
画像を拡大した時のあのギザギザ感をなくし シャープにみせるとあるアルゴリズムをSIMDで改善します!!
拡大 waifu2xDEMO
http://inside.pixiv.net/entry/2015/07/28/230317
今回やったデモの内容は、こちらに詳細があります!!
まとめ
まとめ
ブラウザ上でも、二次元画像みたいなバイナリを効率的に処理する術が増えてて嬉しいです
・WebAssemblyと同じ文脈で語られる パフォーマンス改善技術。 ・大量のデータ同士の計算を ループ文無しでさせることができる。 ・CPUのSIMD命令を、JavaScript APIから 扱うことができる。 ・ぶっちゃけ人間が使うやつじゃないですね!