Mozilla Flux

Mozilla関係の情報に特化したブログです。

Firefox 58でWebAssemblyの起動を大幅に高速化

WebAssemblyは既にメジャーなブラウザすべてでサポートされており、その用途も、たとえばGoogle Earthが移植されるなど、ゲームに限られなくなってきている。もっとも、これまではダウンロード後のコンパイルに時間がかかるという問題があった。Firefox 58では2つの新技術でこの問題に対処し、WebAssemblyアプリケーションの起動を大幅に高速化する。

Making WebAssembly even faster: Firefox’s new streaming and tiering compiler – Mozilla Hacksによれば、1つ目の新技術はストリーミング(Streaming)という。ダウンロードの完了を待たずにコンパイルを開始するもので、この技術はWebAssemblyのファイル形式と相性がいい。単一のファイルのうち、最初にコード部分がダウンロードされるため、これをコンパイルしながら、データ部分のダウンロードの完了を待つことができるのだ。

f:id:Rockridge:20180121174236p:plain:w400
WebAssemblyファイルの構造

もう1つの技術は、段階的(tiered)なコンパイルである。動作は高速だが生成されるコードの最適化が弱いコンパイラと、動作は低速だが生成されるコードの最適化が強力なコンパイラを用意しておき、初めに前者のコンパイラがメインスレッドでWebAssemblyファイルのコンパイルを行う。コードの実行が始まったところで、これと並行して後者のコンパイラが別スレッドで動き出し、コードのコピーに対し最適化を施す。最適化が完了したコードは、メインスレッドのコードと置き換えられる仕組みだ(ホットスワップ)。

f:id:Rockridge:20180121180415p:plain:w600
WebAssemblyファイルの段階的なコンパイル

1段階目のコンパイラは、2段階目のそれよりも10倍から15倍も高速にコンパイルを行うことができる一方、生成されるコードの速度は2段階目のコンパイラと比較して、半分程度を確保している。この2段階のコンパイルはWebAssemblyのすべてのコードに対して適用されるが、それによってWebAssemblyの強みである処理速度を損なうことはない。

このように、Firefox 58では、1段階目のコンパイラがWebAssemblyファイルのダウンロード完了を待たずにコンパイルを開始し、実行中のコードは2段階目のコンパイラが最適化したコードに後で置き換えられるわけだ。では、実際にどの程度の威力を発揮するのだろうか。

GitHub上でMozillaの開発者が公開しているベンチマークを、Firefox 57.0.4(ビルド ID: 20180103231032)とFirefox 58 RC1(ビルド ID :20180115093319)の双方で走らせてみた。12.4MBのWebAssemblyファイルについて、WebAssembly.instantiate()の所要時間を計測するもので、単位はミリ秒(ms)。例えばダウンロード完了からの所要時間が1000msだとすると、1秒あたり12.4MBのコードを処理できていることになる。ベンチマークでは、そのスループットも結果として表示される。5回計測した平均は、以下のとおり。

Firefox 57 Firefox 58
所要時間 2611.9 ms 319.0 ms
スループット 4.8 MB/s 38.9 MB/s

Firefox 58のほうが約8.1倍も高速という結果になった。これだけ速ければ、実環境でも違いを体感できるはず。さらにそう遠くない将来、WebAssemblyのコンパイル結果はHTTPキャッシュに保存され、2回目以降の起動が加速される見通しだ。実行開始から一貫して速いと開発者に知れ渡れば、WebAssemblyアプリケーションの普及に弾みが付くことだろう。