JITコンパイル

JITコンパイル

執筆済 コンピュータ言語処理系

実行時に機械語へコンパイルする。 Just-In-Time。

基本の考え方#

プログラムの実行時間の大半は、 ごく一部のコード(ホットスポット)に費やされる。

そこだけを機械語にコンパイルすれば、 全体をコンパイルするコストを払わずに ほとんどの速度を得られる。

起動 → [[インタプリタ]]で実行(速く始まる)
     → 実行回数をカウント
     → しきい値を超えたら機械語にコンパイル
     → 以降は機械語で実行

AOT に無い強み#

実行時の情報が使える。

情報 利用
実際に来る型 型特化したコードを生成
分岐の偏り よく通る側を直線的に配置
呼ばれる実装 仮想呼び出しを直接呼び出しに
実際の CPU AVX-512 があれば使う

動的型付け言語で JIT の効果が特に大きいのは、 「この変数は実際には常に整数」という情報が 静的には得られないため。

投機と脱最適化#

実行時の観測は未来の保証ではない

「この関数はいつも整数を受け取る」と仮定してコンパイルし、 仮定を検査するガードを入れておく。 仮定が破れたら脱最適化してインタプリタに戻る。

この仕組みがあるから、 静的には不可能な最適化を安全に適用できる。

代償#

  • 起動が遅い(ウォームアップ)
  • コンパイラ自身のメモリと CPU を消費する
  • 生成コードを置くため、実行可能なメモリが要る。 iOS はセキュリティ上これを制限しており、 サードパーティアプリで JIT が使えない

段階的コンパイル#

多くの処理系は複数段階を持つ。

インタプリタ → 簡易 JIT(速くコンパイル) → 最適化 JIT(時間をかける)

V8 の Ignition / TurboFan、 JVM の C1 / C2 がこの構成。

参考文献#

ノート一覧を閉じる