37

アプリケーションで多くの「スタック内省的」コードを観察してきました。これらのコードは、多くの場合、含まれているメソッドがインライン化されていないことに暗黙的に依存しています。このようなメソッドには、通常、次の呼び出しが含まれます。

  • MethodBase.GetCurrentMethod
  • Assembly.GetCallingAssembly
  • Assembly.GetExecutingAssembly

現在、これらの方法に関する情報は非常に紛らわしいと思います。ランタイムは GetCurrentMethod を呼び出すメソッドをインライン化しないと聞いたことがありますが、その効果に関するドキュメントは見つかりません。CLR がクロスアセンブリ呼び出しをインライン化しないことを示す、このような StackOverflow に関する投稿をいくつか見てきましたが、GetCallingAssembly ドキュメントはそれ以外のことを強く示しています。

非常に悪名高い もありますが[MethodImpl(MethodImplOptions.NoInlining)]、CLR がこれを「要求」または「コマンド」と見なすかどうかはわかりません。

契約の観点からのインライン化の適格性について質問していることに注意してください。JITter の現在の実装が実装の問題のためにメソッドを検討することを拒否する時期や、JITter が取引を評価した後に最終的に適格なメソッドをインライン化することを最終的に選択する時期についてではありません。オフ。私はthisthisを読みましたが、最後の 2 つの点により焦点を当てているようです (MethodImpOptions.NoInlining と「エキゾチックな IL 命令」についての言及がありますが、これらは義務としてではなくヒューリスティックとして提示されているようです)。

CLRをインライン化できるのはいつですか?

4

5 に答える 5

23

これはジッターの実装の詳細です。x86 と x64 のジッターには微妙に異なるルールがあります。これは、ジッターに取り組んだチーム メンバーのブログ投稿にさりげなく記載されていますが、チームはルールを変更する権利を留保しています。すでに見つけているようです。

他のアセンブリからのメソッドのインライン化は最も確実にサポートされています。そうでない場合、多くの .NET クラスは非常に悲惨に機能します。Console.WriteLine() 用に生成されたマシン コードを見ると、動作していることがわかります。単純な文字列を渡すと、インライン化されることがよくあります。これを自分で確認するには、リリース ビルドに切り替えて、デバッガー オプションを変更する必要があります。ツール+オプション、デバッグ、一般、「モジュールのロード時にJIT最適化を抑制する」のチェックを外します。

それ以外の場合、 MethodImpOptions.NoInlining が悪意を持っていると見なす正当な理由はありません。そもそもそれが存在する理由です。実際、.NET フレームワークでは、内部ヘルパー メソッドを呼び出す多くの小さなパブリック メソッドで意図的に使用されています。これにより、例外スタック トレースの診断が容易になります。

于 2011-01-11T18:06:38.003 に答える
3

ハンスの答えは正しいですが、必ずしもメソッドがインライン化に適格であるとは限りませんが、メソッドがインライン化に適していない場合については、省略が 1 つあります。

抽象メソッドと仮想メソッドは、 CLR でインライン化できません

メソッドがインライン化される可能性がある条件を絞り込むため、注意することが重要です。

于 2011-01-26T00:24:43.363 に答える
1

このスレッドの MethodBase.GetCurrentMethod のインライン化に関する詳細情報がありますhttp://prdlxvm0001.codify.net/pipermail/ozdotnet/2011-March/009085.html

Paraphrasing heavily, it states that the RefCrawlMark does NOT stop the calling method being inlined. However, RequireSecObject does have the side affect of stopping the caller being inlined.

In addition, the Assembly.GetCallingAssembly and Assembly.GetExecutingAssembly methods do NOT have this attribute.

于 2012-06-09T00:03:30.707 に答える