27

JavaのHotSpotJITは、コンパイルのオーバーヘッドが解釈モードでメソッドを実行するオーバーヘッドよりも低いと予想される場合、メソッドのコンパイルをスキップすることがあることを知っています。.NET CLRは、同様のヒューリスティックに基づいて機能しますか?

4

4 に答える 4

44

注:この回答は「実行ごと」のコンテキストに基づいています。通常、コードはプログラムを実行するたびにJITされます。ngenまたは.NETNativeを使用すると、その話も変わります...

HotSpotとは異なり、CLRJITは常に実行ごとに1回だけコンパイルれます。解釈することはなく、実際の使用法に基づいて以前よりも重い最適化で再コンパイルすることもありません。

もちろん、これは変更される可能性がありますが、v1以降はそのようになっており、すぐに変更されることはないと思います。

利点は、JITが非常に簡単になることです。すでに実行されている「古い」コードを検討したり、無効になったオンプレミスに基づいて最適化を元に戻したりする必要がありません。

.NETを支持する1つのポイントは、ほとんどのCLR言語がデフォルトでメソッドを非仮想化することです。これは、より多くのインライン化を実行できることを意味します。HotSpotは、最初にオーバーライドされるまでメソッドをインライン化でき、その時点で最適化を元に戻します(または、実際のタイプに基づいて、条件付きでインライン化されたコードを使用するために、いくつかの巧妙な処理を実行します)。心配する仮想メソッドが少ないため、.NETは、仮想的なものをインライン化できないという問題をほとんど無視できます。

編集:上記はデスクトップフレームワークについて説明しています。Compact Frameworkは、必要に応じてネイティブコードをスローし、必要に応じて再度JITを実行します。ただし、これはまだHotSpotsの適応最適化とは異なります。

マイクロフレームワークは明らかにJITを行わず、代わりにコードを解釈します。これは、非常に制約のあるデバイスに適しています。(マイクロフレームワークについてよく知っているとは言えません。)

于 2009-08-10T16:20:07.917 に答える
14

.NETランタイムは、実行前に常にコードJITをコンパイルします。したがって、解釈されることはありません。

AndersHejlsbergによるCLRDesignChoices、さらに興味深い読み物を見つけることができます。特にその部分:

私は、MicrosoftがILは常にコンパイルされ、解釈されることはないと決定したことを読みました。命令のタイプ情報をエンコードすると、インタプリタがより効率的に実行されるのにどのように役立ちますか?

Anders Hejlsberg:通訳者が、スタックの一番上にあるものを追跡する必要なしに、指示が言うことを盲目的に行うことができれば、それはより速く進むことができます。たとえば、iaddを検出すると、インタプリタは最初にそれがどの種類の加算であるかを把握する必要はなく、整数の加算であることがわかります。スタックが正しいように見えることを誰かがすでに確認していると仮定すると、そこで時間を短縮しても安全です。通訳者はそれを気にします。ただし、私たちの場合、CLRを使用して解釈されたシナリオをターゲットにすることは意図していませんでした。私たちは常にJIT[Just-in-timecompile]を意図しており、JITの目的のために、とにかく型情報を追跡する必要がありました。私たちはすでにタイプ情報を持っているので、それを指示に入れるために実際に私たちに何も買わない。

Bill Venners:多くの最新のJVM [Java仮想マシン]は、バイトコードを解釈することから始める適応最適化を行います。彼らは、実行時にアプリのプロファイルを作成して、80%から90%の時間で実行されるコードの10%から20%を見つけ、それをネイティブにコンパイルします。ただし、必ずしもこれらのバイトコードをジャストインタイムでコンパイルする必要はありません。メソッドのバイトコードは、ネイティブにコンパイルされ、バックグラウンドで最適化されているため、インタプリタで実行できます。ネイティブコードの準備ができたら、バイトコードを置き換えることができます。解釈されたシナリオを対象としないことで、CLRでの実行へのアプローチを完全に排除しましたか?

Anders Hejlsberg:いいえ、それを完全に排除しているわけではありません。私たちはまだ解釈することができます。通訳用に最適化されていないだけです。私たちは、これまでにしか解釈しない最高のパフォーマンスのインタプリタを書くために最適化されていません。もう誰もそうしないと思います。10年前のセットトップボックスの場合、それは興味深いことだったかもしれません。しかし、それはもはや面白くありません。JITテクノロジーは、複数の可能なJIT戦略を持つことができるようになりました。すばやくリッピングする高速JITを使用することを想像することもできます。その後、特定のメソッドを常に実行していることに気付いたときに、もう少し時間をかけて最適化を行う別のJITを使用します。JITに関してできることはまだまだたくさんあります。

于 2009-08-10T16:19:21.427 に答える
3

メモリが少ないデバイス向けに、将来的にトレースベースの JIT がいくつか見られるのはうれしいことです。主に解釈し、ホットスポットを見つけ、それらをアセンブラに変換してキャッシュします。これは、Google が Android JIT で行っていることであり、 Microsoft Researchはトレースベースの JIT に関する研究プロジェクトを進めていると思います。

「 SPUR: A Trace-Based JIT Compiler for CIL ..」という記事を見つけました。これの一部はいつかCLRに組み込まれるのでしょうか?

于 2010-06-26T00:50:11.807 に答える
0

私はそうは思わないし、そうすべきだとは思わない。

JITは、特定のメソッドが何回呼び出されるかをどのようにして知ることができますか?解釈の頻度が決定に影響しませんか?

また、JITコンパイラが関数を分析して、関数自体を解釈せずに解釈が最適かどうかを判断できるかどうかについても疑問があります。そして、その事実(メソッドの少なくとも1つのパスが行われた)を考えると、最初にどのメソッドがコンパイルされるかを決定しようとするオーバーヘッドを減らすために、各メソッドを単純にコンパイルする方が良いのではないでしょうか?

于 2009-08-10T16:19:52.613 に答える