Lohnt sich EBO wirklich?



  • Wirklich, lohnt sich Empty Base Optimisation?

    Das Musterbeispiel sieht doch immer so aus:

    template <typename T, typename Alloc>
    class vector : Alloc {
      T *data, *data_end, *storage_end;
      Alloc& get_alloc() { return static_cast<Alloc&>(*this); }
    };
    

    Wenn Alloc leer ist, ist hier alles bestens, weil dann ist data an erster Stelle und das will man aus Performanzgründen. Sobald Alloc aber nicht mehr leer ist, wird data nach hinten verschoben und das hat dann negative Auswirkungen auf die Performanz.

    Es gibt zwar Hacks, aber IMHO gibt es keinen standardkonformen Weg, mit EBO zu garantieren, dass Alloc am Ende der Memberliste steht. Bringt EBO deshalb in der Praxis etwas?



  • Inwiefern hat es Auswirkungen auf die Performance, wenn data weiter hinten steht?


  • Mod

    Es braucht keinen Platz! Das ist die Motivation.

    eber schrieb:

    Es gibt zwar Hacks, aber IMHO gibt es keinen standardkonformen Weg, mit EBO zu garantieren, dass Alloc am Ende der Memberliste steht. Bringt EBO deshalb in der Praxis etwas?

    😕 Wo willst du Alloc denn nun haben und warum, obwohl es doch gar nicht "da" ist?

    eber schrieb:

    Bringt EBO deshalb in der Praxis etwas?

    Und wie! Es macht dass du all die schicken durchdesignten Bibliotheken nutzen kannst, ohne dass jeder popelige Smartpointer eine sizeof von > 1000 hat.



  • ipsec schrieb:

    Inwiefern hat es Auswirkungen auf die Performance, wenn data weiter hinten steht?

    vec[n]
    ist, falls data vorne steht, *(&vec + n)
    ansonsten *(&vec + offsetof(vec.data) + n)
    also eine Addition mehr.

    @SeppJ: Es geht um den Fall, dass Alloc doch da ist.


  • Mod

    eber schrieb:

    @SeppJ: Es geht um den Fall, dass Alloc doch da ist.

    Dann greift EBO nicht und die Frage ist hinfällig.

    Oder ist deine Frage, ob EBO etwas bringt, wenn EBO nicht greift? Antwort: Nein. 🙂



  • SeppJ: Dadurch, dass man EBO auszunutzen versucht, hat man in dem Fall einen Nachteil, den man nicht hätte, wenn man den Allokator als Member statt Basisklasse nähme.

    Die Frage: Lohnt sich EBO wirklich?


  • Mod

    Ich nehme mal an, dass deine Frage sich speziell nur auf Allokatoren im Stil der STL bezieht, da du auf andere Anwendungen der EBO (z.B. policy based design) gar nicht eingehst:

    Allokatoren sind (Prä-C++11) in der Regel leer. Wer sich nicht daran hält, weiß wohl (hoffentlich) was er da tut. Dein vermuteter Performancenachteil ist daher nur hypothetisch. Selbst wenn dieser Fall einträte, wäre der Nachteil winzig. Dafür ist der mögliche Gewinn riesig!

    Wenn du dir wirklich Sorgen machst, kannst du mitteln Templatemagie auch zwei unterschiedliche Versionen schreiben, einmal mit Vererbung, einmal mit Komposition.



  • eber schrieb:

    ipsec schrieb:

    Inwiefern hat es Auswirkungen auf die Performance, wenn data weiter hinten steht?

    vec[n]
    ist, falls data vorne steht, *(&vec + n)
    ansonsten *(&vec + offsetof(vec.data) + n)
    also eine Addition mehr.

    Nope, ist es nicht. Da fehlt eine Indirektion, der vector enthält lediglich einen Pointer auf den Speicher. Abgesehen davon, verfügen die meisten CPUs wohl über entsprechende Addressierungsmodi, sodass das offsetof da kaum bis praktisch bzw. sogar tatsächlich gar keinen Unterschied macht...



  • //vec[n] =>
    *((*(&vec))+n)
    //vs
    *((*(&vec+4))+n)
    //und der compiler macht daraus in beiden Fällen
    *(*datapointerpos+n)
    

Anmelden zum Antworten