Speicheroverhead new



  • Hoi,
    Was ist denn ungefähr der Speicheroverhead bei der Heapallozierung per new?

    Angenommen

    int* v = new int;
    

    Wie viel Speicher geht dafür drauf? Offensichtlich 4 Bytes + eventuelles Alignment + ein paar interne Pointer?
    Was sagt der Standard dazu? Wird das int an einer Addresse mod 4 == 0 angelegt (was zu erwarten wäre)? (Auf ner x86/x64 Kiste)

    Danke und Grüße,
    Flo



  • Ich würde mal schätzen sizeof(zeiger), eventuelles Padding würde ich ausschließen, da es sich ja nicht um eine Struktur handelt.

    Der Speicher der alloziert wird, der sollte auch nur die engeforderte Größe einnehmen. (alles rein intuitive Aussagen)

    Dass der Standard dazu etwas sagt bezweifle ich, da das ja schon ziemlich systemnah ist.


  • Mod

    Alle Objekte werden mit ihrem maschinenabhängigen Alignment angelegt. Speicherreservierungen ohne zur Compilezeit festehendem Typ werden so ausgerichtet, dass das Alignment für alle denkbaren Typen passt. Darüber hinaus wird vom Standard nichts festgelegt.

    Praktisch gilt:
    1. Alignment "verbraucht" keinen Speicher, außer du allokierst wirklich Speichermengen, die nicht ins Raster passen. Dann hast du eventuell kleine Lücken, so ähnlich wie bei den Paddingbytes in Strukturen. Kommt auch drauf an, wie der Speichermanager intern arbeitet.
    2. Irgendwo wird in der Praxis noch die Größe des Bereiches gespeichert, eventuell auch noch ein zugehöriger Zeiger auf den Anfang. Also ungefähr ein bis zwei intptr_t.

    Frage ist auch: Wieso sollte diese Information wichtig sein? Deine Frage klingt so, als wolltest du eigentlich etwas ganz anderes wissen.



  • Ethon schrieb:

    Wie viel Speicher geht dafür drauf? Offensichtlich 4 Bytes + eventuelles Alignment + ein paar interne Pointer?
    Was sagt der Standard dazu?

    Der sagt nix dazu ... soweit ich weiß.

    Ethon schrieb:

    Wird das int an einer Addresse mod 4 == 0 angelegt (was zu erwarten wäre)? (Auf ner x86/x64 Kiste)

    malloc liefert jedenfalls einen Zeiger zurück der so aligned ist, dass du ohne Probleme alles Mögliche (Zeiger, double, ... ) da speichern kannst, ohne dass es Probleme bzgl Alignment macht. Ich schätze, das sieht bei dem default new-Operator nicht anders aus.



  • Wie gross der Speicheroverhead ist kann man so nicht sagen. Das kommt auf die Implementierung der Dynamic Memory Allocation an.

    Die Alignment Boundaries haengen vom Betriebssystem ab. Siehe zum Beispiel hier: http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86
    Etwas ueberraschend ist dabei, dass Windows ein double 8-byte aligned und Linux 4-byte.



  • Danke schön, scheint also nicht so dramatisch wie angenommen. 🙂

    Frage ist auch: Wieso sollte diese Information wichtig sein? Deine Frage klingt so, als wolltest du eigentlich etwas ganz anderes wissen.

    Och, ich mache gerade bezüglich dem Speicherverbrauch meines Programmes ein paar Worst-Case Abschätzungen und da ich aus Polymorphiegründen große Mengen kleiner Objekte auf dem Heap anlege war der Overhead von new ein unbekannter Parameter in meinen Überlegungen der mich gestört hat.



  • Ethon schrieb:

    Och, ich mache gerade bezüglich dem Speicherverbrauch meines Programmes ein paar Worst-Case Abschätzungen und da ich aus Polymorphiegründen große Mengen kleiner Objekte auf dem Heap anlege war der Overhead von new ein unbekannter Parameter in meinen Überlegungen der mich gestört hat.

    Viel relevanter wäre wohl die Performance.

    Ansonsten: einfach eigenen allokator verwenden der in chunks allokiert. Wenn deine Objekte alle gleich groß sind, dann geht das ziemlich einfach.



  • Viel relevanter wäre wohl die Performance.

    Ein langsames Programm ist besser als ein Programm, das garnicht läuft weil der Speicher nicht reicht. 😃
    Performance ist weniger da Problem, das meiste dümpelt mehr oder weniger tot im Speicher rum bis es mal gebraucht wird. Ich versuch mal nicht den genauen Sachverhalt hier zu erklären, geht jedenfalls nicht wirklich anders.

    Ansonsten: einfach eigenen allokator verwenden der in chunks allokiert. Wenn deine Objekte alle gleich groß sind, dann geht das ziemlich einfach.

    Da eigentlich alle "Problemobjekte" gleich lange leben wäre es sogar als Stackallocator machbar ... aber solange es mit new klappt, ist es mir recht und ich denke erst an Optimierungen wenn es ein Problem wird. Passe halt nur auf dass Optimierungen nachträglich kein Problem sind. 🙂


  • Mod

    vector?



  • Ethon schrieb:

    int* v = new int;
    

    Wie viel Speicher geht dafür drauf? Offensichtlich 4 Bytes + eventuelles Alignment + ein paar interne Pointer?

    Kommt drauf an.
    Es gibt Allokatoren die dafür < 4.1 Byte (amortisiert) brauchen.
    Andere brauchen dafür >= 16 Byte.

    Was sagt der Standard dazu? Wird das int an einer Addresse mod 4 == 0 angelegt (was zu erwarten wäre)? (Auf ner x86/x64 Kiste)

    Der Standard schreibt nicht vor was int für ein Alignment zu haben hat. Am besten du liest dir die entsprechenden Stellen selbst durch wenn dich interessiert was der Standard zum Thema Alignment genau vorschreibt, und was der Implementierung überlassen wird.



  • Small Object Allocator?


Anmelden zum Antworten