Skip to content

MS_ReadyToRunAndTieredCompilation

nishi_74322014 edited this page Sep 1, 2026 · 1 revision

ReadyToRun + Tiered Compilation

概要

段階コンパイル

  • JIT の最適化を段階的に行い、パフォーマンスを改善する仕組み。
  • 一部のシナリオではプリコンパイル済みのコードより速くなる。

補足(なぜ「段階」なのか): JIT には根本的なトレードオフがある。

起動速度 定常性能
最適化なしで即コンパイル 速い 遅い
最適化ありでコンパイル 遅い 速い

どちらか一方を選ぶと他方が犠牲になる。
そこで「まず速くコンパイルして動かし、
よく呼ばれるものだけ後から最適化し直す
」という折衷にしたのが
Tiered Compilation である。

1 回しか呼ばれないメソッドに最適化コストを払わない
という点が本質的な効きどころになる。

詳細

仕組

ReadyToRun (R2R)

コンパイル時に Tier 0 なネイティブコードも同時に生成する仕組み。

Tiered Compilation

Tier 0 なネイティブコードを実行時に Tier 1 へ差し替える仕組み。

段階

コンパイルの段階

Tier 0

  • 初めて呼ばれるメソッドは一律「最適化なし」で JIT コンパイル
  • 使用頻度の高いメソッドは実行環境へ最適化されたコードへの差し替えが出来る。

Tier 1

  • 呼ばれた回数をカウントして、一定数を越えたら「最適化あり」で JIT コンパイル
  • 実行中でも戻り先アドレスに補正をかけるので、実行中に JIT コンパイル可能

移行メモ: 元ページは「オン中でも」「オン中に」と表記されていたが、
文意から「実行中」(メソッドがスタック上にある状態)と解釈して改めた。
技術的には **OSR(On-Stack Replacement)**と呼ばれる仕組みで、
.NET 7 で既定有効になった。これにより
「長いループを 1 回だけ回すメソッド」も途中で Tier 1 に差し替えられる。

補足(R2R と AOT の違い): 名前が紛らわしいので整理しておく。

方式 実体 JIT 特徴
JIT のみ IL のみ配布 必要 起動が遅い
ReadyToRun (R2R) IL + プリコンパイル済みネイティブ 必要(Tier 1 で使う) 起動が速い。サイズは増える
Native AOT ネイティブのみ 不要 最速起動・最小メモリ。リフレクション等に制約

R2R は「IL を捨てない」のが要点で、
起動時は事前生成コードを使い、ホットパスだけ実行環境に合わせて
再 JIT する(= AOT の起動速度と JIT の最適化を両取りする)。

<PublishReadyToRun>true</PublishReadyToRun>

なお 初回が遅い! で扱われる
「初回リクエストが遅い」問題に対して、R2R は有効な打ち手になる。

補足(既定値): 現在の .NET では

  • Tiered Compilation は既定で有効(.NET Core 3.0 以降)
  • Tiered PGO(プロファイルに基づく最適化)は .NET 8 で既定有効
  • R2R は発行時に明示的に指定する(既定は無効)

ベンチマークを取る際は、Tier 1 に上がるまでウォームアップすること。
ウォームアップ無しの計測は Tier 0 の性能を見ているだけになりやすい
(BenchmarkDotNet はこれを自動で行う)。

参考


Tags: 移行, .NET開発, .NET Core

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally