.NET auf Warp 9 beschleunigen: Ngen
Geschrieben von: Christian Holm Das Ngen (Native Image Generator) Tool, welches dem .NET Framework SDK beiliegt, erstellt ein Abbild Ihrer Assembly in Maschinensprache im Global Assembly Cache (C#/VB.NET kompilieren zu IL, nicht Maschinensprache) . Dies beschleunigt die Ausführung gewaltig, da beim Erstaufruf der Assembly diese bereits in Maschinensprache vorliegt und nicht mehr durch den JIT Compiler dynamisch generiert werden muß. Schon aus der Einleitung sollte ersichtlich sein, daß der Native Image Generator nichts mit irgendwelchen Eingeborenen oder deren Bildererstellung zu tun hat, obwohl der Name "verleitend" ist. Mit Native Code (Maschinensprache) ist eine Datei gemeint, die kompilierten Sourcecode enthält, der einem Prozessor-spezifischen Bytecode entspricht. .NET Execution ProcessMit der Verwendung des .NET Frameworks hat sich einiges am Executionprozeß einer Anwendung geändert. Dieser sieht schematisch für eine .NET Applikation folgendermaßen aus: Wenn der Sourcecode geschrieben ist, wird es Zeit, diesen zu kompilieren. Verwendet man C# oder VB.NET, so wird der Sourcecode nicht auf Maschinensprache kompiliert, sondern auf IL (Intermediate Language), die zusammen mit MetaData in die Assembly (EXE oder DLL zum Beispiel) geschrieben wird. Wichtig: es ist nicht verpflichtend für eine Programmiersprache auf IL zu kompilieren. Managed Code kann auch in Maschinensprache vorliegen (und das macht sich Ngen zunutze). Die Kompilierung auf Native Code geschieht erst beim ersten Aufruf des Programms durch einen JIT-Compiler. Erst wenn diese Schritte erfolgreich abgeschlossen werden, wird Ihr Programm ausgeführt. Hierbei sind wir schon beim Knackpunkt bzw. Flaschenhals. Für den Fall, daß Ihre .NET Applikation viele Assemblies umfaßt, müssen diese beim ersten Aufruf erst auf Native Code kompiliert werden. Bei vielen Assemblies kann dies sehr lange dauern. Natürlich werden die Assemblies nicht bei jedem Funktionsaufruf, sondern eben nur beim ersten kompiliert - solange sich an der Signatur der Assembly nichts ändert. Vorhang auf für NGenMit dem Ngen Tool haben Sie nun die Möglichkeit diese Assemblies sofort auf Native Code zu kompilieren. Diese werden im GAC (Global Assembly Cache, \WinNT\assembly) als "Native Images" (bzw. Win 2000: "PreJit") geflaggt, damit der JIT-Compiler bzw. die Runtime weiß, daß diese Assemblies nicht mehr zu kompiliern sind, da diese schon als Native Code vorliegen. Da die gesamte Arbeit vom Ngen Tool erledigt wird, brauchen Sie weder in Ihrem Sourcecode oder bei der Ausführung irgendwelche Anweisungen bzw. Switches hinzufügen - die Runtime inspiziert automatisch die Assemblies und entscheidet je nach gesetztem Flag was zu tun ist. Jetzt werden Sie vielleicht zwei Fragen brennend interessieren:
Methoden die aus irgendwelchen Gründen nicht mit dem Ngen Tool auf Native Code kompiliert werden können, werden vom Tool nicht in das Native Image inkludiert. Wenn nun die Runtime diese Native Code Assembly bearbeitet, werden exkludierte Methoden trotz des "Native Images" Flag mit dem JIT Compiler kompiliert. Die zweite Frage läßt sich nur unscharf beantworten. Unscharf deshalb, weil mehrere Faktoren die Startupphase einer Applikation beeinflussen können. Aber als Grundregel sollte gelten, daß das Vorkomplieren von Assemblies auf jeden Fall für clientseitige Applikationen und bei sehr vielen gleichzeitig zu ladenden Assemblies angewandt werden sollte. NGen im EinsatzNatürlich wollen wir nun dieses Tool ausprobieren und seine Handhabung kennenlernen. Dafür habe ich ein kleines Szenario vorbereitet, und etwas (einfachen) Sourcecode geschrieben. Der Sourcecode ist heute nur Mittel zum (Optimierungs)Zweck, deshalb entfällt seine Vorstellung. Der erste Schritt ist klarerweise die Kompilierung auf MSIL. Bei Erfolg wird eine DLL Assembly generiert, mit der wir nun weiterarbeiten werden. Jetzt kommen wir zum interessanten Teil: die Erstellung eines Native Images aus der Assembly. Da das Ngen Tool im Moment eine Konsolenanwendung ist, öffnen wir zuallererst ein Kommandoprompt-Fenster (cmd.exe). Hinweis: Wenn Sie das .NET Framework SDK installiert haben, haben Sie hoffentlich die Option "Register .NET Environment Variables" angeklickt. Ansonsten werden Sie bei der Arbeit mit .NET Tools am Kommandoprompt einige Probleme haben. Um dies nachträglich zu korrigieren rufen Sie das Setup des .NET Frameworks in der Auflistung der installierten Software (Control Panel, Add or Remove Software) auf und ändern Sie die Einstellung. Wenn Sie hingegen Visual Studio .NET installiert haben, sind eigentlich keine Änderungen vorzunehmen. Sie verwenden jedoch statt des herkömmlichen Kommandoprompts (cmd.exe) das Visual Studio .NET Command Prompt, welches Sie in der Microsoft Visual Studio .NET Programmgruppe unter Visual Studio .NET Tools finden. Im Kommandoprompt wechseln wir in das Verzeichnis wo sich die Assembly befindet, und können nun sofort mit Hilfe des Ngen Tools ein Native Image erstellen, indem wir folgendes eingeben: ngen SimpleExample.dll Und schon wird ein Native Image erstellt. Wo ist jetzt das Native Image der Assembly? Sie finden es im GAC (\WinNT\assembly): Wie Sie sehen, hat unsere Assembly unter der Type-Bezeichnung den Eintrag "Native Images", zuvor war es "Application Extension". Hierzu sind einige Anmerkungen zu machen: Da ich der Einfachheit halber auf eine Assembly-Info Datei verzichtet habe, besteht die Versionsnummer aus einer GUID und die Culture Info ist auf default gesetzt. Weiters ist zu bemerken, daß ich das SN (Strong Name) Utility hier nicht verwendet habe, und somit auch kein Public Key angegeben ist. Im Anwendungsfall sollte dies aber nicht die Regel sein. Natürlich können Sie auch - falls erforderlich - einige Switches angeben. Allgemein sieht der Syntax für die Verwendung des Tools so aus: ngen [Optionen] AssemblyPfad AssemblyName AssemblyPfad ist natürlich der Pfad wo sich die Assembly befindet. Da wir das Tool im gleichen Verzeichnis ausgeführt haben, wo sich unsere Assembly befindet, brauchen wir dies nicht angeben. AssemblyName ist natürlich der eigentliche Name der Assembly. Falls erforderlich, können Sie auch mehr als nur eine Angabe zu einer Assembly machen. Options ist hier ein Platzhalter für die möglichen Switches. Interessant sind:
SchlußbemerkungEmpfundene Geschwindigkeit ist bei vielen Anwendungen das wichtigste Performancekriterium. Gerade hier zeigen sich bei .NET Schwächen, sobald die Anwendung eine gewisse Größe erreicht - das JITen fordert seine Zeit. Diesen Startnachteil kann man mit NGen mehr als ausgleichen - wird die Anwendung am Zielrechner "pre-JITed", dann passt NGen den Code auf die Zielprozessorarchitektur an. Und das kann sogar zu Geschwindigkeitsvorteilen gegenüber Nicht-.NET Anwendungen führen. Verwandte ArtikelWenn Sie jetzt Fragen haben...Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten. Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist. Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.
Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.
©2000-2006 AspHeute.com |