nutzlose selbstreferenzrückgabe automatisch wegoptimiert?



  • hi
    wenn ich soetwas habe:

    class A{
     public:
     A& foo(){return *this;};
    }
    int main(){
    A a;
    a.foo();
    a.foo();
    a.foo();
    a.foo();
    a.foo();
    a.foo();
    return 0;
    }
    

    ist die rückgabe der eigenreferenz komplett nutzlos.

    wird soetwas automatisch wegoptimiert oder taucht es aus anderen gründen nicht im maschienencode auf?

    ps.:ich möchte nicht die rückgabe der eigenreferenz löschen, da jemand auch

    a.foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo().foo();
    

    schreiben können soll.



  • Wenn der Compiler den Aufruf inline erweitert, dann wird er das wegoptimieren.

    Wenn der Aufruf nicht inline erweitert wird, dann stehen die Chancen auch wirklich ganz schlecht dass er es wegoptimiert (ich glaube dass das kein einziger C++ Compiler macht, obwohl es theoretisch möglich wäre).

    Allerdings beschränkt sich der Overhead vermutlich auf ein "move Register -> Register" vor dem "ret", und ist damit klein verglichen mit den Kosten des nicht-inline Funktionsaufrufs.



  • also würde sich das ganze mit einem expliziten inline beheben......

    Allerdings beschränkt sich der Overhead vermutlich auf ein "move Register -> Register" vor dem "ret", und ist damit klein verglichen mit den Kosten des nicht-inline Funktionsaufrufs.

    wenn man es sehr oft aufruft merkt man evt etwas^^
    macht sicher nichts aus, aber man muss ja nicht extra overhead einbauen



  • wsderf schrieb:

    also würde sich das ganze mit einem expliziten inline beheben......

    Was meinst du damit? __declspec(forceinline) und dergleichen?
    Bin ich grad kein Fan davon. Der Compiler weiss meistens recht gut was inline Sinn macht und was nicht. Sieh einfach zu dass der Compiler die Chance hat es inline zu erweitern. D.h. Funktion im Header-File definieren und/oder ggf. LTCG aufdrehen.

    Allerdings beschränkt sich der Overhead vermutlich auf ein "move Register -> Register" vor dem "ret", und ist damit klein verglichen mit den Kosten des nicht-inline Funktionsaufrufs.

    wenn man es sehr oft aufruft merkt man evt etwas^^
    macht sicher nichts aus, aber man muss ja nicht extra overhead einbauen

    Wenn die Performance SO wichtig ist, dann lass die Funktion nix zurückgeben UND sieh zu dass der Compiler sie inline erweitern kann. Und verwende zusätzlich Profile-Guided-Optimization.
    Wenn die Performance nicht ganz SOOO wichtig ist, dann lass es wie es ist, und wende dich wichtigeren Dingen zu.



  • Was meinst du damit?

    asdf.h
    class A{
     public:
     A& foo();
    }
    
    asdf.cpp
    #include"asdf.h"
    inline A& A::foo(){return *this;}
    

    das meine ich.



  • Das hat mit inlining nichts zu tun.



  • wsderf schrieb:

    also würde sich das ganze mit einem expliziten inline beheben......

    Deine Funktion ist in der Klasse definiert, also ist sie sowieso schon inline.



  • womit dann?
    afaik hat das die selbe wirkung, als würde ich die funktion direkt im header definieren.
    und das wurde in meinem lehrbuch halt explizites inline genannt.



  • 314159265358979 schrieb:

    Das hat mit inlining nichts zu tun.

    Falsch. Das kann sehr wohl geinlined werden. Nur setzt das einen modernen Compiler sowie die passende Option voraus. Nennt sich LTO.

    Btw: warum gibt "vorraus" im Text ein vorraus? Währden Schreifehler kleich mytt nem Zäsur beschtrafft?



  • Du deklarierst mit dem Schlüsselwort "inline" keine Funktion, die geinlined werden soll. Das ist einfach falsch. Tu mir den gefallen und benenne dich nach einer irrationalen Zahl, z.B. e, wenn du schon versuchen musst, mich zu flamen.



  • Um mal ein wenig Licht ins Dunkel zu bringen. inline ist nichts weiter als eine Empfehlung für den Compiler und kann maximal zur Vermeidung von Doppeldefinitionen missbraucht werden. Ob eine Funktion geinlined wird hängt von verschiedenen Faktoren ab.
    - Sichtbarkeit der Implementierung
    - Rekursionstiefe
    - und andere Umstände, die ein inlining erschweren

    Einzeiler, die Sichtbar sind, dürften in der Regel aber immer geinlined werden.



  • inline ist _KEIN_ Hinweis an den Compiler, die Funktion zu inlinen.



  • 31415926535897 schrieb:

    benenne dich nach einer irrationalen

    Meine Lieblingszahl ist irrational. Zumindest nach π eine der berühmtesten irrationalen Zahlen. Wenn sie etwas nicht ist, dann transzendent (was e wiederrrum wäre). Aber wer φ nicht kennt, versteht das auch nicht. Übrigens wollte ich dich nicht flamen sondern nur berrichtigen.

    31415926535897 schrieb:

    Du deklarierst mit dem Schlüsselwort "inline" keine Funktion, die geinlined werden soll.

    Das lasse ich nun aber bleiben, weil ich deinen Satz schlicht nicht verstanden habe.

    Daher erkläre ich kurz, was LTO ist: Inlining während dem Linken.



  • Um mal ein wenig Licht ins Dunkel zu bringen. inline ist nichts weiter als eine Empfehlung für den Compiler und kann maximal zur Vermeidung von Doppeldefinitionen missbraucht werden. Ob eine Funktion geinlined wird hängt von verschiedenen Faktoren ab.
    - Sichtbarkeit der Implementierung
    - Rekursionstiefe
    - und andere Umstände, die ein inlining erschweren

    Einzeiler, die Sichtbar sind, dürften in der Regel aber immer geinlined werden.

    also wäre es in dem fall egal ob ich das da hinschreibe oder nicht?

    asdf.h
    class A{
     public:
     A& foo();
    }
    
    asdf.cpp
    #include"asdf.h"
    inline A& A::foo(){return *this;}
    


  • Unser Freund, der Herr Irrational wird sagen: Nein, das ist egal.
    In der Praxis wird das auch so sein.

    Aber der C++ Standard sagt nirgendwo, dass das so ist, denn die Entscheidung liegt schlussendlich beim Compiler. Und wie sich diese in Zukunft entwickeln ist ungewiss (um nicht ein provozierendes absehbar zu schreiben). Nur eines ist sicher: verlassen kannst du dich darauf nicht, gehe also vom schlimmsten Fall aus.



  • Okay nochmal! Ob eine Funktion geinlined wird entscheidet ganz allein der Compiler. Das Schlüsselwort inline ermöglicht es dir nur, die Funktion in verschiedenen Übersetzungseinheiten zu definieren, ohne das in jeder eine Funktionsdefinition gemacht wird. Wie das für den Linker aussieht, wenn die Funktion nicht geinlined werden konnte, kann ich aber nicht beantworten. Das selbe Problem existiert aber grundsätzlich auch bei Templates.



  • Wie das für den Linker aussieht, wenn die Funktion nicht geinlined werden konnte, kann ich aber nicht beantworten.

    Was soll dann grossartig sein?



  • 314159265358979 schrieb:

    inline ist _KEIN_ Hinweis an den Compiler, die Funktion zu inlinen.

    Ach?

    C++ Standard - 7.1.2 schrieb:

    The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.

    No twinkey!



  • Ob die Funktion inline expandiert wird, ist nicht beobachtbar und kann daher vom Standard nicht vorgeschrieben werden. Und eigentlich ist es unnötig, das zu sagen, aber es ist überhaupt nicht möglich, sich "darauf zu verlassen" (@1618033988749894848204586) oder nicht.


Anmelden zum Antworten