BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース 失敗した場合に備えて:NET 3.5 SP1でのJIT拡張機能

失敗した場合に備えて:NET 3.5 SP1でのJIT拡張機能

ブックマーク

.NETプラットフォームでは、たいていのコンパイラーはVBやC#コンパイラーでは最適化されない。それどころか、CLRのJust in TimeコンパイラーがILを受け取り、それをネイティブマシンコードに変換するまで遅延される。このため、JITへの変更は以前にコンパイルされたアセ ンブリに多大な影響を及ぼしかねない。

大きな影響を受ける領域の1つに、機能呼び出しのインライン化がある。これまでJITはインライン化メソッドに非常に保守的であった。Vance Morrison氏はその理由を説明している(リンク)

インライン化が必ずしも他より優れているとは限らない。インライン化は、実行される命令数を少なくする(控えめに述べても、呼び出しおよびリターン命令は実行 されないため)。しかし、結果コードを巨大にする可能性がある(たいていの場合)。われわれの多くは直感的に、(たとえば1K バイトの)大きなメソッドをインライン化することは意味をなさず、呼び出しサイトを小さくする非常に小さなメソッド(呼び出し命令が5バイトであるため) をインライン化するのがつねにうまくいくと本能的に知っているだろう。しかしその間にあるメソッドについてはどうか?

興味深いことに、コードを大きくするにつれて、それをさらに遅くしている。その理由は本質的にメモリが遅く、コードが巨大化すればするほど、最速のCPU キャッシュ(L1と呼ばれている)には入らなくなる。その場合、プロセッサは他のキャッシュ(L2と呼ばれる)からフェッチされるまで3から10サイクル 停止する。そしてそこに入らなければ、メインメモリに入る(10サイクル以上かかる)。短いループで実行するコードではこの結果は問題ではない。すべての コードが最速のキャッシュ(通常は64K)に「うまく入る」からである。しかしながら「標準的な」コードでは、多くのメソッドから大量のコードを実行する ため、「大きくなればなるほど、遅くなる」という結果は非常に明白である。またコードが大きくなることは、開始時にディスクからコードを取り除くために、 より大きなディスクI/Oを必要とすることを意味し、アプリケーションがゆっくり起動することを意味する。

サービスパック 1については、Microsoftはコードサイズおよび呼び出しがループにあるかどうかに基づいた新たなヒューリスティックを採用している。通常の状況下 で、結果のマシンコードが呼び出しサイトのオリジナルバージョンよりも小さい場合に、機能はインライン化される。キャッシュミスはパフォーマンスに大きな 影響を及ぼしかねないので、これはできるだけ多くのコードがCPUのキャッシュに入るようにするために実行される。

ループ内で作業する場合、一部例外がある。おそらく機能は頻繁に呼び出されるので、CLRは元の呼び出しサイトの5倍までの大きさの機能をインラインすることができる。バリュータイプの最適化などのその他の条件は、許可されるサイズをさらに拡大する場合がある。

原文はこちらです:http://www.infoq.com/news/2008/09/JIT-Inlining

この記事に星をつける

おすすめ度
スタイル

BT