IonMonkey in Firefox 18

これは Mozilla の JavaScript チームのブログに投稿された IonMonkey in Firefox 18 の翻訳です。
この翻訳にあたり、Constellation さんにレビュー協力をしていただきました。改めてお礼申し上げます。


IonMonkey in Firefox 18

今日、私たちは新たなる JavaScript JIT エンジン、IonMonkey を Firefox 18 で有効にしました。IonMonkey によって、私達の JavaScript のパフォーマンスとコンパイラアーキテクチャは大きく前進することとなります。1年にも及んで高度に焦点をあてて取り組んできた IonMonkey チームを代表して、私達も IonMonkey が搭載されたことに興奮を隠せていないことも述べておきます。

SpiderMonkey は、JIT コンパイラとしての歴史を重ねています。しかしながら、そのいずれにおいても、Java や C++ のように、皆さんがよく目にする典型的なコンパイラを形作る鍵となるコンポーネントを持ち合わせていませんでした。古くは TraceMonkey(*1)、最近では JägerMonkey のどちらも、JavaScript から機械語へとほぼ直接的に変換を行っています。そこには中間となるステップが存在していません。これらのコンパイラでは、変換結果を眺めてさらなる最適化を施すといった、一歩引いて見返すような処理が存在していなかったのです。

IonMonkey は、まさにその処理を可能にする新たなアーキテクチャの名前です。これは基本的には3つの処理のステップを持ちます。

  1. JavaScript を中間表現に変換する
  2. 多くのアルゴリズムを実行し中間表現を最適化する
  3. 最適化された中間表現を機械語に変換する

パフォーマンスや保守性の向上に限らず、将来的な JavaScript コンパイラの研究をより簡単にするものであるという事実に私達は興奮を覚えます。最適化アルゴリズムの追加と処理パイプラインへの挿入、そして、それが何を行っているかの参照が可能になったのです。

ベンチマークについて

それでは、実際に IonMonkey はベンチマークでどの程度のスコアを出したのでしょうか?
IonMonkey は長期間に渡って実行されるアプリケーションをターゲットにしています(ごく短期間しか実行されないアプリケーションについては JägerMonkey にフォールバックします)。私のデスクトップマシン(Windows 7 Professional が動いているMac Pro)にて Kraken benchmark と Google V8 benchmark を実行しました。Kraken benchmark の実行は、Firefox 17 では 2602ms もかかってしまいました。一方、Firefox 18 では、おおよそ26%の改良である1921msです。グラフは、一分間に実行可能な回数を表したもので、グラフが高いほど良いスコアを示します。

Kraken benchmarkの時間あたりの実行回数

Google V8 benchmark では、Firefox 15 は8474、Firefox 17 では9511というスコアを出しています。ですがFirefox 18では10188というスコアを出し、Firefox 17比で7%、Firefox 15比では20%もの改良となりました。

V8 benchmarkのスコア

私達は未だ長い道の途中にいます。次の数か月ではこの極上のアーキテクチャに対して、主要なベンチマークとリアルワールドのアプリケーションを狙った改良を続けていきます。

チーム

私達にとって、IonMonkey の最も素晴らしいな側面の一つは、よく調整されたチームの努力があったことです。2011年の6月ごろ、私たちは詳細な計画案を作成し、この計画が1年にわたるものであると公算を立てました。Andrew Drake, Ryan Pearl, Andy Scheff, Hannes Verschoreら4人のインターンとともにスタートし、それぞれが IonMonkey の基盤となる重要なコンポーネントを実装しました。最終的なコードベースにも彼らの成果はすべて存在しています。

2011年の8月過ぎには、フルタイムのメンバーによるチームを発足させました。このチームは現在、Jan de Mooij, Nicolas Pierron, Marty Rosenberg, Sean Stangl, Kannan Vijayan, そして私(訳注:元記事の筆者である David Anderson )によって構成されています(SpiderMonkey の開発に参加していた Chris Leary, ならびに2012年夏のインターンとして参加していた Eric Faust についても述べておかないといけませんね)。この1年、このチームは IonMonkey を前進させ、アーキテクチャーを増築し、その設計とコードの品質は私たちが作りうる中で最高のものにし、JavaScript のパフォーマンスを向上させることに邁進してきました。

全員が同じ目標を持ち、プロジェクトの成功に向けて協力して取り組んできたことが報われました。皆が各々の役割を果たしてくれたことに感謝しています。

技術について

今後数週間にわたり、主要なIonMonkeyのコンポーネントとそれらがどのように動作しているかについてブログに書く予定です。ここに簡単ではありますが、現在のIonMonkeyにおける最適化技術を紹介しようと思います。

  • ループ内不変式の移動 (Loop-Invariant Code Motion, LICM)
    可能な場合、ループ外に命令をくくり出す
  • 大域値番号付け (Sparse Global Value Numbering, GVN)
    冗長なコードの強力な除去形式
  • 線形探索レジスタ割り付け (Linear Scan Register Allocation, LSRA)
    Hotspot JVMで使用されている(最近まではLLVMでも使用されていた(*2))レジスタ割り付けスキーム
  • 無用コードの除去 (Dead Code Elimination, DCE)
    使用されていない命令の削除
  • 数値の範囲の解析 (Range Analysis)
    解析によって数値の範囲が定まることによる、配列アクセスの境界チェックの事前削除(bug 765119の解決後に有効になる予定です)

特に注目してほしい点として、IonMonkey は私たちの Tier-1 プラットフォームの上で今すぐにでも動作するということを述べておきます。CPU ごとに異なるコード生成部の再実装が最小限に済むように、高度に抽象化されたコンパイラアーキテクチャとなっています。コンパイラの大部分が x86、x86-64、 ARM(ほとんどのスマートフォン及びタブレットで使わている CPU アーキテクチャです)で共有されています。殆どの箇所において、コアとなるアセンブラインターフェースだけが異なっているのです。全ての CPU は異なる命令セットを持っているためです(ARM の場合は x86 とは全く異なるものです)。私たちはこの成果を特に誇りに思っています。

いつから使えますか?

IonMonkey は、現在の Firefox Nightly である Firefox 18のデスクトップ版ではデフォルトで有効になります。同様にモバイル版の Firefox でもまもなく有効にする予定です。Firefox 18 は 10月8日 に Auroraへ、11月20日に Beta へと移行する予定です。

*1: TraceMonkey は正確には中間表現層を持っていましたが、残念ながら、ごく限定的なものでした。最適化はその場で実行されており、その中間表現のデータ構造は、事後からの最適化が不可能なものでした。
*2(訳注:本翻訳にて追加): LLVM Project Blog: Greedy Register Allocation in LLVM 3.0