korea1 Geschrieben 3. Juli 2003 Geschrieben 3. Juli 2003 hi, ich wurde hier gerade hingesetzt, um quellcode zu kommentieren. kann mir mal bitte jmd von euch erklären, was es mit dem inline und this auf sich hat. programmierkenntnisse vorhanden, aber sehr wenig c++ danke korea1 Zitieren
Crush Geschrieben 3. Juli 2003 Geschrieben 3. Juli 2003 This ist ein Zeiger der auf die eigene Objektinstanz verweist und (jedenfalls im Visual Studio) wird die aktuelle Methodenliste eingeblendet, man kann ja nicht immer alles zu 100% im Kopf haben. Im Endeffekt ist es dasselbe, als wie wenn man auf ein Objekt die Methodenliste per Punktoperator aufruft, nur daß This dies eben über ein Zeiger macht und dieser nur innerhalb der Klassendeklaration und -definition selbst existiert. Wenn man also This als Rückgabeparameter angibt, wird immer ein Zeiger auf die aktuell abgearbeitete Instanz zurückgegeben - und dieser Zeiger ist natürlich bei jedem neuen Objekt ein anderer. Inline zwingt den Compiler, Funktionen- & Methoden nicht als Unterprogramme aufzurufen, welche durch unnötige Heap- und Stackbelastungen (Retten vom Prozessor-Einsprungspunkt, CPU-Flags, Registern, Ablegen und initialisieren von Variablen, etc. und das gleiche nochmal beim Rücksprung) bei entsprechend kurzen Routinen ein Mehrfaches der Rechenzeit benötigt, als wie wenn man diese Routine direkt an der Stelle im Code einfügt, am besten auch noch mit Parameterübergabe in Prozessorregistern. Daher ist die Optimier-Kombination Inlining und Register, wenn nicht gerade entsprechendes Auto-optimieren aktiviert ist, die ideale Kombination um viel Geschwindigkeit aus dem Programm rauszuholen ohne tatsächlich den Code zu verändern. Dadurch wächst allerdings bei häufiger Verwendung die Codegröße an, aber der Geschwindigkeitzuwachs ist dieses bei entsprechendem Einsatz absolut wert. Eine Faustregel ist bei mir, daß Methoden mit häufigen Aufrufen und nicht mehr als ca. 3-4 Befehlszeilen gerne inline kompiliert werden. Zitieren
Klotzkopp Geschrieben 3. Juli 2003 Geschrieben 3. Juli 2003 Original geschrieben von Crush Inline zwingt den Compiler, Funktionen- & Methoden nicht als Unterprogramme aufzurufen,Das ist so nicht ganz richt. Das Schlüsselwort inline ist nur eine Empfehlung für den Compiler, und nicht zwingend. Die meisten modernen Compiler wissen besser als der Programmierer, wo das Inlinen sich lohnt, und wo nicht. IMHO sollte man inline nur dann verwenden, wenn durch Profiling nachgewiesen wurde, dass es etwas bringt. Manche Compiler bieten aber auch Möglichkeiten, das Inlinen zu erzwingen, z.B. mit __forceinline bei MSVC++. Zitieren
nic_power Geschrieben 3. Juli 2003 Geschrieben 3. Juli 2003 Original geschrieben von Klotzkopp Das ist so nicht ganz richt. Das Schlüsselwort inline ist nur eine Empfehlung für den Compiler, und nicht zwingend. Die meisten modernen Compiler wissen besser als der Programmierer, wo das Inlinen sich lohnt, und wo nicht. Insbesondere bei Architekturen wie SPARC, die auf Sprünge bereits auf Prozessorebene optimiert sind. Hier ist der Aufruf von Unterprogramme unter Umständen sogar schneller als ein Inlining, da die Daten beim Sprung nicht in irgendwelchen Registern gerettet werden müssen. Nic Zitieren
Knuddlbaer Geschrieben 3. Juli 2003 Geschrieben 3. Juli 2003 da die Daten beim Sprung nicht in irgendwelchen Registern gerettet werden müssen Verstehe ich nicht. Bei Inline wird der Quelltext direckt an die Stelle eingefügt. Warum muß da was in Registern gerettet werden ? Bei einem Sprung dagegen muß der Stack Arbeit leisten ?! *Mal nach aufklräung umschau* Zitieren
nic_power Geschrieben 3. Juli 2003 Geschrieben 3. Juli 2003 Hallo, es gibt Architekturen, bei denen Sprünge nicht über den Stack abgewickelt werden, sondern beispielsweise über Windowing-Mechanismen (SPARC) oder bestimmte Calling-Conventions (HPPA). Dabei werden die Parameter direkt in den Registern übergeben. Die SPARC-Architektur unterscheidet zwischen in, out und local Register. Parameter werden von einer Funktion in die Outregister geschrieben, danach erfolgt der Aufruf eines weiteren Funktion. Diese findet die Parameter in ihren in-Registern wieder, was prinzipiell einer Umbenennung der Register entsprichen. Zusätzlich hat jede Funktion jedoch einen eigenen unabhängigen Satz von lokalen Registern. D.h. nach dem Aufruf steht ihr ein neuer Satz Register zur Verfügung, der direkt verwendet werden kann, ohne das Daten auf dem Stack gesichert werden müssen. Für die aufgerufenen Funktion sind die lokalen Register des Aufrufers also nicht sichtbar. Interessant wird das ganze, wenn eine einzelen Funktions sehr viele Variablen verwendet, die nicht mehr in die lokalen Register passen. In diesem Fall müssten die Werte im RAM zwischengespeichert werden, was sehr viel Zeit kostet. Wesentlich effizienter ist in diesem Fall jedoch der Aufruf einer entsprechenden Unterroutine (insbesondere bei CPUs mit vernünftigen Branchprediction- und Prefetch-Mechanismen, im Optimalfall dauert ein Sprung einen Takt, ohne dass eine Pipeline-Stall auftritt), da hier die Speicherzugriffe entfallen können und neue lokale Register zur Verfügung stehen. Es ist natürlich klar, dass die Anzahl der In/Out und Lokalen Register sowie der Register-Fenster beschränkt ist. Aber bereits mit 8 Register-Fenstern und jeweils 8 in/out/locals lassen sich Funktionsaufrufe bis in die achte Unterfunktion mit 8 Parametern und 8 lokalen Variablen realisieren, ohne das ein einziges mal auf den Stack zugegriffen werden muss (praktisch gibt es ein paar Einschränkungen, die jedoch nichts am Prinzip ändern). Einen Minifoliensatz habe ich mal auf meiner Webseite unter http://www.nleymann.de/misc/sparc.pdf abgelegt. Die erste Folie dürfte die interessanteste sein, da hier das Registerwindowing in Zusammenhang mit Funktionsaufrufen zu finden ist. Nic Zitieren
Knuddlbaer Geschrieben 4. Juli 2003 Geschrieben 4. Juli 2003 Auf Hardwareebene sehr interesannt, nur als C++ Programmierer hat man da keinen Einflus drauf. (Was passiert wenn foo().doAnything aufgerufen wird, und dahinter verbergen sich massig andere Aufrufe ?!) Ich gehe dann davon aus das der eingesetzte Compiler den Source optimiert. Wie wird das eigentlich gehandelt wenn: foo(veryBigAndComplexObject byValue) { byValue.Anything(); } Aufgerufen wird ? Zitieren
nic_power Geschrieben 4. Juli 2003 Geschrieben 4. Juli 2003 Hallo, aus dem Grund ist "inline" auch nur ein Hinweis für den Compiler, da die Auswirkungen je nach Prozessorarchitktur unterschiedlich sind und das inlining nicht zwangsläufig zu schnellerem Code führen. Zumal die Optimierung auf Geschwindigkeit nicht die einzige Möglichkeit ist, Du kannst ja auch auf Code-Göße optimieren. In diesem Fall ist es empfehlenswert auf ein inlining komplett zu verzichten (beispielsweise über den passenden Compilerswitch). Nic Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.