headerdateien nach konvention erstellen ist langsam?



  • hallo liebe community.
    ich habe noch eine weitere frage.

    wenn ich meine klasse v3 (das ist ein 3d-vektor) in einer headerdatei v3.h nur deklariere und die ganzen elementfunktionen in v3.cpp definiere (also ganz konservativ vorgehe), ist mein programm deutlich langsamer als wenn ich die elementfunktionen direkt in der headerdatei definiere.

    also meine v3.h sieht grob folgendermaßen aus:

    #ifndef _V3_H
    #define _V3_H
    
    class v3 {
    private: //...
    public: 
    // ...
    v3 operator+(v3);
    //...
    };
    
    v3 operator*(double,v3);
    //...
    #endif
    

    und die v3.cpp so:

    //...
    v3 v3::operator+(v3 vkt) { /* ... */ }
    v3 operator*(double zahl,v3 vkt) { /* ... */ }
    

    wenn ich es aber so umgestalte, dass die elementfunktionen direkt in der klassendeklaration definiert werden, wird die rechenzeit ungefähr halbiert!

    das hat aber den nachteil, dass ich die globalen operatorfunktionen nur inline definieren kann, weil es sonst als doppelte definition vom compiler angemeckert wird. (und alle anderen nachteile, die sich halt ergeben).

    nun meine fragen:
    wie kann ich die vorzüge des konventionellen headers mit der höheren geschwindigkeit kombinieren?
    und vor allem: warum wird es mit normalem headerlayout und v3.cpp so langsam?

    es handelt sich um eine physikalische simulation mit opengl-darstellung -> rechengeschwindigkeit ist also nicht unwichtig.

    ich benutze dev-c++ 4.9.9.2 (mit standardcompilereinstellungen)

    ich habe nichts weiter geändert außer die anordnung der funktionsdeklarationen/-definitionen in den einzelnen programmdateien. es muss also daran liegen.



  • weil methoden welche im header definiert worden sind vom compiler als inline kandidaten drankommen.

    methoden welche in der cpp hingegen nicht.

    bei ner methode die zb 100000mal pro sekunde aufgerufen wird, ist der zusätzliche call overhead einer normalen methode dann doch ein merkbarer faktor.



  • achso.
    deshalb habe ich auch keinen unterschied bei der rechengeschwindigkeit gemerkt, als ich die funktionen mal inline und mal nicht-inline definiert habe.

    wie kann ich die funktionen inline definieren UND in die v3.cpp schreiben?

    wenn ich einfach in v3.h und v3.cpp "inline" davorschreibe, gibt es die meldung:

    "v3.h [Warning] inline function const GLdouble& v3::operator[](int) const' used but never defined" und "[Linker error] undefined reference tov3::operator[](int) const'"



  • hermesasl schrieb:

    wie kann ich die funktionen inline definieren UND in die v3.cpp schreiben?

    Meines Wissens gar nicht, zumindest nicht mit der gegenwärtigen Sprachversion und den Compilern. 😞



  • also wäre eine schnelle und trotzdem konventionelle möglichkeit, alle inlinefunktionen in der headerdatei zu lassen und die anderen (konstruktoren etc.) in v3.cpp zu definieren?



  • hermesasl schrieb:

    ich benutze dev-c++ 4.9.9.2 (mit standardcompilereinstellungen)

    Davon solltest du wegkommen. Dev-C++ ist veraltet und wird nicht mehr weiterentwickelt. Zu empfehlen sind die kostenlosen IDEs Microsoft Visual C++ 2008 Express und Code::Blocks.

    inpimp schrieb:

    weil methoden welche im header definiert worden sind vom compiler als inline kandidaten drankommen.

    methoden welche in der cpp hingegen nicht.

    Seit wann ist das so? Der Compiler kann doch auch Inline-Optimierungen bei Funktionen in Implementierungsdateien vornehmen. Auf Linker-Ebene spielt es ja keine so grosse Rolle, wo die Funktionen definiert wurden. Ansonsten wäre die ganze Inlining-Optimierung nicht wirklich sinnvoll...

    hermesasl schrieb:

    also wäre eine schnelle und trotzdem konventionelle möglichkeit, alle inlinefunktionen in der headerdatei zu lassen und die anderen (konstruktoren etc.) in v3.cpp zu definieren?

    Ja, zum Beispiel. Du kannst aber auch einen anderen Header mit den Inline-Funktionen machen und diesen am Ende der Klassendefinition einfügen, damit du die Trennung zwischen Schnittstelle und Implementierung bewahren kannst. Wobei es meiner Ansicht nach wie gesagt möglich sein sollte, dass der Compiler Nicht-Inline-Funktionen optimiert. Probier einfach einen aktuellen Compiler aus.



  • danke für die empfehlung zu code::blocks ... das gefällt mir ganz gut.

    leider compiliert es eine datei nicht und ich weiß nicht, was falsch ist.

    template <class P>
    inline P max(P a,P b) {
          return (a>b)?c:b;
    }
    

    fehlermeldung:

    error: expected `)' before "a"
    

    kann da schnell jemand was sagen?
    sorry, wollte wegen der kurzen frage kein extra-topic öffnen



  • sollte heißen: return (a>b)?a:b;

    das problem besteht weiterhin



  • hermesasl schrieb:

    sollte heißen: return (a>b)?a:b;

    das problem besteht weiterhin

    Hmmm.. ich bin mir nicht ganz sicher, aber hast du es schonmal so probiert:

    return (a > b ? a : b);
    


  • Nexus schrieb:

    inpimp schrieb:

    weil methoden welche im header definiert worden sind vom compiler als inline kandidaten drankommen.

    methoden welche in der cpp hingegen nicht.

    Seit wann ist das so?

    Falsche Frage. Richtiger: "Seit wann ist das nicht mehr so?" Was du als selbstverständlich annimmst erfordert schon einigen Aufwand seitens des Compiler/Linker-Gespanns.



  • Bei dir ist std::max nicht im globalen Namensraum bekannt? Sowieso würde ich das benutzen, und bei einem eigenen Funktionstemplate einen anderen Namen wählen...



  • okay, danke für den tipp. funktioniert jetzt



  • Bashar schrieb:

    Falsche Frage. Richtiger: "Seit wann ist das nicht mehr so?" Was du als selbstverständlich annimmst erfordert schon einigen Aufwand seitens des Compiler/Linker-Gespanns.

    Dann hätte man womöglich meine Frage falsch verstanden. 😉

    Und ich schätze es sehr, dass mir der Compiler und der Linker einige Arbeit abnehmen. Tut mir leid, wenn ich den Compilerbauern zu wenig Respekt gezollt habe. 😉



  • Seit wann ist das so? Der Compiler kann doch auch Inline-Optimierungen bei Funktionen in Implementierungsdateien vornehmen.

    Gute Compiler tun das auch.

    MSVC z.B. kann das seit Version 8 aka. 2005 (ab Version 7.1 theoretisch, praktisch aber nicht zu empfehlen da zu buggy).

    GCC kann das mit den passenden Einstellungen vermutlich auch, hab das aber nicht überprüft.



  • hustbaer schrieb:

    Seit wann ist das so? Der Compiler kann doch auch Inline-Optimierungen bei Funktionen in Implementierungsdateien vornehmen.

    Gute Compiler tun das auch.

    MSVC z.B. kann das seit Version 8 aka. 2005 (ab Version 7.1 theoretisch, praktisch aber nicht zu empfehlen da zu buggy).

    GCC kann das mit den passenden Einstellungen vermutlich auch, hab das aber nicht überprüft.

    Nur daß ich das richtig verstehe, die Rede ist doch von Inline-Funktionen, die in einer anderen Übersetzungseinheit definiert sind, richtig?

    Kann man irgendwo nachlesen, wie das beim MSVC funktioniert?



  • dooooomi schrieb:

    Kann man irgendwo nachlesen, wie das beim MSVC funktioniert?

    Stichwort "linktime code generation".

    EDIT:
    Zum Beispiel http://msdn.microsoft.com/en-us/magazine/cc301698.aspx



  • natürlich habt ihr recht mit LTCG.

    aber der thread starter wird mit seinem devc++ mitgelieferten compiler diesbezüglich nicht weit kommen 🙂



  • inpimp schrieb:

    natürlich habt ihr recht mit LTCG.

    aber der thread starter wird mit seinem devc++ mitgelieferten compiler diesbezüglich nicht weit kommen 🙂

    Darüberhinaus ändert LTCG ja auch nichts an der One Definition Rule, für die das Keyword inline immernoch von essentieller Bedeutung ist 🙂

    Man kann es aber trotzdem mal erwähnt haben, da es schnell heißt, dass Inlining über Codefilegrenzen hinweg nicht möglich sei.



  • LordJaxom schrieb:

    Man kann es aber trotzdem mal erwähnt haben, da es schnell heißt, dass Inlining über Codefilegrenzen hinweg nicht möglich sei.

    Das hat dann aber mit dem inline-Schlüsselwort nichts mehr zu tun, sondern ist eine Optimierung, die vollständig hinter den (durch den C++-Standard gegebenen) Kulissen abläuft.



  • inpimp schrieb:

    aber der thread starter wird mit seinem devc++ mitgelieferten compiler diesbezüglich nicht weit kommen 🙂

    War also doch nicht so schlecht, ihm davon abzuraten. 😉


Log in to reply