JIT Optimierungen vom Feinsten

8

Ich habe viel darüber gelesen und gehört, wie JIT-Compiler Optimierungen vornehmen können, die für Native-Code-Compiler unmöglich sind und dass diese Optimierungen enorme Leistungssteigerungen bewirken können.

Also habe ich mich gefragt, was sind die wichtigsten Optimierungen, die das .NET Framework oder die JVM machen, die ein nativer Compiler nicht kann? Und wie bringen diese enorme Leistungssteigerungen?

Ich weiß nicht, ob ich diese Frage richtig formuliert habe. Ich schätze, ich habe in den Kommentaren eine Menge zu erklären.

    
ApprenticeHacker 13.04.2012, 05:51
quelle

2 Antworten

4

Ich kann ein Beispiel für eine Optimierung geben. Angenommen, Sie haben irgendwo eine Funktion. (Betrachten Sie dies als C-ähnlichen Pseudocode.)

%Vor%

Das ist passend vage. Angenommen, Sie haben nur eine konkrete Klasse in Ihrem gesamten Bild, die von MyClass : MyConcreteClass erbt. In diesem Fall kann der JIT doSomething und getWidgets inline enthalten. Wenn es über den Typ weiß, der von getWidgets zurückgegeben wird, dann kann es vielleicht auch% code% inline enthalten.

Unter der Annahme, dass doSomethingElse keine finale / versiegelte Klasse ist, kann ein Compiler vor dem Zeitpunkt seine Methode nicht inline einbinden (er würde nicht wissen, welche Funktionen inline sind); Für den ganzen Compiler weiß, gibt es hundert verschiedene Implementierungen von MyClass .

Ein JIT kann jedoch für den aktuellen Status des Bildes optimieren. Es kann zu Beginn jedes Aufrufs eine Überprüfung auf MyClass installiert werden, die sicherstellt, dass function ein% co_de ist %, und führen Sie dann die Inline-Version aus. Wenn Sie ein Modul dynamisch mit einer anderen konkreten Klasse laden, die von x erbt, wird die Überprüfung fehlschlagen und das JIT wird die Funktion erneut generisch kompilieren.

Dies sind die einzigen Arten von Optimierungen, die JIT-Compilern zur Verfügung stehen, die für Compiler außerhalb der Zeit nicht verfügbar sind: Optimierungen, die Informationen über den dynamischen Status des Programms verwenden und das Programm neu kompilieren Programm entsprechend.

Beachten Sie, dass einige Compiler, die vor der Zeit arbeiten, Tricks ausführen können, die normalerweise JIT-Compilern zugeschrieben werden. Zum Beispiel interprozedurale Optimierung (oder globale Optimierung) und profilgesteuerte Optimierung. GCC und Clang können beide Tricks anwenden, aber die meisten Leute lassen sie aus, da sie zusätzliche (menschliche) Arbeit benötigen, um sie zu aktivieren. JIT-Compiler können diese Optionen aktiviert lassen, ohne Endbenutzer zu belästigen.

Großer Leistungsschub: Von JIT-Compilern habe ich im Allgemeinen keinen großen Leistungsschub gehört. C- und C ++ - Programme sind immer noch schnell ohne JIT. Und viele Leute bevorzugen immer noch Fortran für numerische Arbeit (mit gutem Grund).

Fußnote: Ich bin mir Ihrer Terminologie nicht sicher. Sind die meisten JITs auch native Code-Compiler? Die anderen Arten von Compilern außer JIT würde ich "vor der Zeit" oder AOT nennen, oder vielleicht "statisch". (Und dann ist da noch die unglaublich unscharfe Grenze zwischen "kompiliert" und "interpretiert".)

    
Dietrich Epp 13.04.2012, 08:22
quelle
1

Javascript ist ein viel besseres Beispiel, da es Compiler nicht so freundlich behandelt wie die JVM oder CLR.

JIT-Compiler können konkrete spezialisierte Repräsentationen für Javascript-Klassen erzeugen, was für statische Compiler schwierig ist, da die Klassen jederzeit während der Programmausführung geändert werden können. Sie können die aufgerufenen Funktionen auch spekulativ auf Basis der tatsächlichen Typen inline einreihen (Dietrich Epp hat dies bereits in seiner Antwort erklärt).

Die Videos unter Ссылка erklären diese Optimierungen auf anschauliche Weise.

    
Patrick 13.04.2012 10:27
quelle