Frage

Ich habe eine Menge von „Stack-introspektiven“ Code in Anwendungen beobachtet, die oft implizit auf ihren haltigen Verfahren beruhen nicht für ihre Richtigkeit inlined werden. Solche Verfahren häufig Anrufe beinhalten:

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

Jetzt finde ich die Informationen über diese Methoden rund um sehr verwirrend zu sein. Ich habe gehört, dass die Laufzeit wird keine Inline, die GetCurrentMethod nennt, aber ich kann keine Dokumentation zu diesem Zweck finden. Ich habe Beiträge auf Stackoverflow mehrmals gesehen, wie dieses , funktioniert die CLR angibt keine Inline-Quer Montage Anrufe, aber die GetCallingAssembly Dokumentation stark nichts anderes ergibt.

Es gibt auch die viel geschmähte [MethodImpl(MethodImplOptions.NoInlining)], aber ich bin nicht sicher, ob der CLR hält dies für eine „Anfrage“ oder als „Befehl.“

Beachten Sie, dass ich über inlining bin zu fragen Förderfähigkeit vom Standpunkt des Vertrages, nicht , wann aktuelle Implementierungen des Jitters Rückgangs Methoden zu prüfen, wegen Schwierigkeiten bei der Umsetzung, oder über wenn das Verwackeln schließlich endet Auswahl , um ein berechtigtes Inline nach den Kompromissen zu beurteilen. Ich habe diese und diese , aber sie scheinen mehr konzentrierte sich auf die letzten beiden werden Punkte (es ist vorbei erwähnt von MethodImpOptions.NoInlining und „exotischen IL Anweisungen“, aber diese scheinen, als Heuristik vorgestellt werden und nicht als Pflichten ).

Wenn die CLR erlaubt Inline?

War es hilfreich?

Lösung

Es ist ein Jitter-Implementierung Detail, die x86 und x64 Bammel haben leicht unterschiedliche Regeln. Dies wird beiläufig in Blog-Posts von Teammitgliedern dokumentiert, dass auf dem Jitter gearbeitet, aber die Teams behalten sicherlich das Recht vor, die Regeln zu ändern. Sieht aus wie Sie bereits gefunden sie.

Inlining Methoden aus anderen Baugruppen sind mit Sicherheit unterstützt, viele der .NET-Klassen funktionieren würden ziemlich kläglich, wenn das nicht der Fall ist. Sie können es bei der Arbeit sehen, wenn Sie an dem Maschinencode für Console.WriteLine erzeugt aussehen (), wird es oft inlined, wenn Sie einen einfachen String übergeben. Um dies zu sehen für sich selbst, müssen Sie das Release-Build wechseln und eine Debugger-Option ändern. Werkzeuge + Optionen, Debugging, General, untick "Suppress JIT-Optimierung auf Modullast".

Es gibt sonst keinen guten Grund zu der Annahme MethodImpOptions.NoInlining verleumdet, es ist ziemlich viel, warum es in erster Linie existiert. Es ist in der Tat absichtlich in dem .NET-Framework auf viele kleine öffentliche Methoden verwendet, die eine interne Hilfsmethode nennen. Es macht Ausnahme Stack-Traces leichter zu diagnostizieren.

Andere Tipps

Hans Passant Antwort ungeachtet, hier zuerst ein paar Hinweise, wie 2004, und weiter unten einige weitere aktuelle Informationen. Sie unterliegen Veränderung, aber sie geben Sie eine Idee, was zu suchen, wenn Sie eine Methode geeignet machen wollen für inlining:

die JIT wird nicht inline:

  • Methoden mit MethodImplOptions.NoInlining markiert
  • Methoden größer als 32 Bytes von IL
  • Virtuelle Methoden
  • Methoden, die einen großen Wert Typ als Parameter
  • Methoden auf MarshalByRef Klassen
  • Methoden mit komplizierten Flußgraphen
  • Methoden treffen andere, exotischere Kriterien

Insbesondere ist MethodImplOptions.AggressiveInlining , die angeblich heben die 32 Byte Grenze (oder was auch immer es geschieht in diesen Tagen zu sein und für Ihre Plattform).

.Net 3.5 hinzugefügt Heuristik, die helfen, es festzustellen, ob zu Inline oder nicht Inline , die wahrscheinlich eine gute Sache ist, obwohl es es schwieriger für den Entwickler macht die Jitter-Entscheidung vorherzusagen:

Ein Zitat aus dem Artikel:

  1. Wenn inlining Fabrikate Code kleiner als der Anruf es ersetzt, ist es immer gut. Beachten Sie, dass wir über die NATIVE Codegröße sprechen, nicht die IL-Code-Größe (das ganz anders sein kann).

  2. Je mehr eine bestimmte Website-Aufruf ausgeführt wird, desto mehr wird sie von inlning profitieren. So Code verdient in Schleifen mehr zu inlined als Code, der nicht in Schleife ist.

  3. Wenn Exposes wichtige Optimierungen inlining, dann ist inlining wünschenswerter. Insbesondere Methoden mit Werttypen Argumente wegen Optimierungen wie dies mehr als normal profitieren und somit mit einer Vorspannung, diese Methoden Inline ist gut.

So ist die Heuristik des X86 JIT-Compiler verwendet wird, ein Inline gegeben Kandidat.

  1. Schätzen Sie die Größe der Aufrufstelle, wenn die Methode wurde nicht inlined.

  2. Schätzen Sie die Größe der Aufrufstelle, wenn es inlined wurden (dies ist eine Schätzung auf der IL basiert, verwenden wir eine einfache Zustandsmaschine (Markov Model), erstellt eine Menge realer Daten unter Verwendung dieser Schätzer Logik zu bilden)

  3. Compute ein Multiplikator. Standardmäßig ist es 1

  4. Erhöhung des Multiplikators, wenn der Code in einer Schleife ist (die aktuelle heuristischen Bumps es bis 5 in einer Schleife)

  5. den Multiplikator erhöhen, wenn es wie struct Optimierungen sieht in kickt.

  6. Wenn InlineSize <= NonInlineSize * Multiplikator des inlining tun.

Während Hans' beantworten korrekt ist, gibt es eine Unterlassung, die nicht unbedingt zu, wenn ein Verfahren zur inlining berechtigt ist, aber wenn eine Methode ist nicht .

Zusammenfassung und virtuelle Methoden sind nicht für inlining in der CLR .

Es ist wichtig zu beachten, wie es die Bedingungen schnitzt, unter denen ein Verfahren können inlined werden.

Es gibt mehr Informationen über inlining von MethodBase.GetCurrentMethod auf diesen Thread http: //prdlxvm0001.codify.net/pipermail/ozdotnet/2011-March/009085.html

Paraphrasieren stark, heißt es, dass die RefCrawlMark stoppt nicht die Rufmethode inlined wird. Allerdings hat RequireSecObject die Seite hat Auswirkungen auf den Anrufer zu stoppen inlined wird.

Darüber hinaus sind die Assembly.GetCallingAssembly und Assembly.GetExecutingAssembly Methoden haben dieses Attribut nicht.

Es gab einen Artikel auf MSDN veröffentlicht im Jahr 2003 genannt Schreiben High Performance Managed Apps das deckt die Umrisse mehrere Kriterien ganz klar:

  • Methoden, die größer als 32 Byte IL nicht inlined werden.
  • sind virtuelle Funktionen nicht inlined.
  • Methoden, die komplexe Flusskontrolle haben, werden nicht in ausgekleideten sein. Komplexe Flusskontrolle ist jede Flusssteuerung anders als if / then / else; in diesem Fall, Schalter oder während.
  • Methoden, die Ausnahmebehandlung Blöcke enthalten, werden nicht inlined, obwohl Methoden, die Ausnahmen auslösen sind noch Kandidaten für inlining.
  • Wenn eine der formalen Argumente der Methode structs ist, wird das Verfahren nicht inlined werden.

Sacha Goldshtein Blog Artikel im Jahr 2012 auf aggressiver inlining in der CLR viel von dem gleichen Rat hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top