memcpy vs operator=



  • Hi Leute!
    Ich hab eine kleine Performancefrage.
    Und zwar habe ich eine Klase für Quaternionen geschrieben, die auf Geschwindigkeit optimiert ist.
    Ich habe bis jetzt schon per Inline Assembler die Arithmetik-Funkionen auf SS2 optimiert.
    Aber etwas stört mich noch ein wenig: Der Konstruktor!

    Bis jetzt sieht einer davon in etwa so aus:

    inline Quaterion::Quaterion(const Quaterion& q)
    {
        w= q.w;
        a= q.a;
        b= q.b;
        c= q.c;
    }
    

    Wäre es schneller, wenn er so aussieht:

    inline Quaterion::Quaterion(float fW, float fA, float fB, float fC)
    {
       memcpy(this, &q, sizeof(Quaterion));
    }
    
    Ich weiß, es gibt andere Flaschenhälse.
    Vieleicht lass ich es der Anschaulichkeit halber auch so wie es ist.
    Ich wollts halt mal gern wissen.
    


  • Blaze schrieb:

    Ich hab eine kleine Performancefrage.

    Nur eine Performancefrage oder ein tatsächliches (per Profiler nachgewiesenes) Performanceproblem?

    In deinem Fall würde ich auf jeden Fall die dritte Möglichkeit nehmen: Initialisierungsliste. Auch wenns sich am Ende alles nicht viel nehmen sollte.



  • 1. ist das inline sinnlos (und verwirrend)

    2. glaube ich nicht, dass das memcpy-verhalten definiert ist... imho ist memcpy nur für PODs definiert, diese wiederrum sind aber durch das fehlen des ctors/dtors/op= eindeutig bestimmt...
    außerdem würd ich meinen, dass memcpy da (unter vernünftigen annahmen) gar nicht schneller sein kann...

    ich würd auch für die initialisierungsliste plädieren - allerdings auch ohne das (evtl.) performance-problem...

    ps: ich glaub w, a, b, c sind nicht gerade die gebräuchlichsten namen bei quaternions ;o)



  • Gut, dann nehme ich die Listen!

    Was sind PODs?

    Was ist mit größeren Klassen, die mal 64Byte groß sind?
    Ist eigentlich auch egal. Ich konzentriere mich dann lieber auf andere Flaschenhälse!

    Diese Variablen a, b und c sind in einer union mit x, y, und z. So ist für jedem das seine dabei;)



  • Zum Thema POD's und noch anderen Begriffen hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-194356.html

    Was ist mit größeren Klassen, die mal 64Byte groß sind?

    Was meinst du genau? - Ich bin auch der Meinung, dass der Compiler dir da eigentilch das Maximum der Initialisierung rausholen kann. Ob das jetzt für 64 Byte oder nur für 1 Byte ist spielt ja keine Rolle..



  • Blaze schrieb:

    Diese Variablen a, b und c sind in einer union mit x, y, und z. So ist für jedem das seine dabei;)

    Wozu die Union? Sowas wir nur in den allerseltendsten Fällen benötigt.



  • Ein Union, damit keine Fkt aufgerufen werden muss, nehme ich an...
    Nicht, dass es performance-mäßig einen unterschied machen würde - aber ich find es in dem fall so auch ästhetischer^^

    bb



  • @Blaze:
    Wenn du auf Performance optimieren willst, dann pack alles in die Header.
    Und wieso inline Assembler? Damit verhinderst du bloss bei vielen Compilern dass sie irgendwas optimieren.
    Wieso nicht stattdessen SSE(2) intrinsics?



  • Blaze schrieb:

    Hi Leute!
    Ich hab eine kleine Performancefrage.
    Und zwar habe ich eine Klase für Quaternionen geschrieben, die auf Geschwindigkeit optimiert ist.

    Vermeide einfach benutzerdefinierte Copy-Konstruktoren und Zuweisungen. Die kann der Compiler auch automatisch generieren. Nur manchmal machen die vom Compiler generierten Version etwas falsches. Nur dann sollte man einschreiten und seine eigenen Versionen definieren. Beim Design sollte man darauf achten, solche Situationen, wo die benutzerdefinierten Funktionen erforderlich sind, zu minimieren.

    Wenn Du für einen Typ T einen Copy Ctor selbst deklarierst, obwohl er gar keinen gebraucht hätte und nur PODs als Elemente besitzt, machst Du aus T ein "nicht-trivial-kopierbaren Typ" (C++0x Terminologie). Das heißt, wo sonst noch memcpy in Frage gekommen wäre, muss nun der benutzerdefinierte Copy Ctor "aufgerufen" werden (inline mal ignoriert).

    Ich denke nicht, dass Du einen benutzerdefinierte copy ctor bzw operator= für diesen Fall brauchst. Stimmts oder habe ich recht? :p

    Achso: Was machen denn die vom Compiler generierten Versionen? Ganz einfach: eine Elementweise Kopie/Zuweisung, falls möglich. Falls nicht möglich, gibt's eben keinen copy ctor bzw operator=. Zum Beispiel kann der Compiler kein operator= generieren, wenn Du eine Referenz als Element hast, etc.

    Gruß,
    SP


Log in to reply