BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース V8がWebAssembly SIMDをサポート

V8がWebAssembly SIMDをサポート

原文(投稿日:2020/02/05)へのリンク

WebAssembly SIMDプロポーザルが、実験段階としてではあるが、GoogleのJavaScriptエンジンであるV8に提案された。V8がSIMD(Single Instruction, multiple data)をサポートするのは、データの並列処理を活用することによる、音声処理やビデオ処理、マシンラーニングといった計算集約的なタスクの促進が目的だ。

SIMDオペレーションは現在のCPUアーキテクチャのほとんどがサポートしているが、その方法については様々だ。そのため、現在のWebAssembly SIMDプロポーザルは、現行のハードウェアで広くサポートできるような、限定的なオペレーションセットの定義を目標にしている。その中には、新しいv128値型で表現される、固定長128ビットデータの演算も含まれている。これに関するすべては、特別なwasm_simd128.hヘッダファイルの中でプログラマに公開されている。

以下の例は、2つの配列の要素を乗算して、結果を別の配列に格納する方法を示したものだ。

#include <wasm_simd128.h>

void multiply_arrays(int* out, int* in_a, int* in_b, int size) {
  for (int i = 0; i < size; i += 4) {
    v128_t a = wasm_v128_load(&in_a[i]);
    v128_t b = wasm_v128_load(&in_b[i]);
    v128_t prod = wasm_i32x4_mul(a, b);
    wasm_v128_store(&out[i], prod);
  }
}

実際には、LLVMの自動ベクトル化による最適化があるので、このようなSIMD固有の処理を使用する必要はなく、通常のループ演算によってSIMDオペレーションを表現すれば、コンパイラの最適化がSIMDオペレーションに変換してくれる。

void multiply_arrays(int* out, int* in_a, int* in_b, int size) {
  for (int i = 0; i < size; i++) {
    out[i] = in_a[i] * in_b[i];
  }
}

前述のように、SIMDの目的は、計算集約型アプリケーションを促進することにある。Google Researchが公開しているV8 SIMDを使ったデモの大半は、ハンドトラッキングクレジットカード認識、拡張現実といった、コンピュータ画像処理をベースとするタスクに関するものだ。ハンドトラッキングの場合、SIMDを使用しない場合には3FPだったものが、SIMD並列処理を使用した場合にはピーク時15~16FPSになり、5倍のパフォーマンス向上を実現している。GoogleでTensorFlow for JavaScriptの開発に携わるエンジニアのNikhil Thorat氏も、自身のチームにおける経験として、WebAssembly SIMDを現実世界のモデルで使用して3倍のスピードアップを実現したことをツイートしている。

V8 WebAssemblyはChrome canaryでサポートされているが、有効にするには--enable-features=WebAssemblySimdフラグを指定する必要がある。現在のサポートはまだ実験段階であり、WebAssembly SIMDプロポーザルの進展に伴って変更される予定だ。

ブラウザでSIMを実装したのはV8が初めてではなく、John McCutchan氏がDart言語を使用して行ったのが最初の事例だ。事実として、WebAssembly SIMDプロポーザルの中には、Dart SIMD仕様の要素を継承した部分がある。WebAssemblyのSIMオペレーションのサポートに関しても、すでにWasmerWasmtimeといったWebAssemblyランタイムによって提供されている。

この記事に星をつける

おすすめ度
スタイル

BT