Speicherverwaltung intrusiver Container



  • Laut Dokumentation von Boost.Intrusive wird Speicherverwaltung nicht von den Containern selbst, sondern extern gehandhabt. Daduch könne man sich Allokationen sparen. Jedoch habe ich dazu bisher wenig Konkretes gefunden.

    Wie sieht das in der Praxis aus, irgendwo müssen die Elemente ja dynamisch abgelegt werden. Hat man dafür einen herkömmlichen STL-Container oder einen Memory-Pool?



  • Du machst einfach new und delete.

    idR hast du einen intrusive container ja nicht einfach als ersatz zu einem stl-container sondern in einer speziellen situation. und dort managed du die resourcen dann auch speziell.

    ich verwende intrusive container zB dann, wenn ich allokationen sparen will - weil man 100% kontrolle über das resourcen management hat. das bedeutet aber auch, dass man eine auf die situation abgestimmte strategie verwenden muss.



  • Shade Of Mine schrieb:

    Du machst einfach new und delete.

    Dann hat man aber vergleichsweise viele Allokationen, nämlich für jedes Element. Wo liegt der Vorteil gegenüber std::list ? Seit C++11 muss man ich schliesslich nicht mehr kopieren, sondern kann move oder emplace anwenden.

    Mir ist bewusst, dass man durch Intrusive Containers einige andere Vorteile hat, aber mich interessiert hier vor allem Speicherverwaltung...

    Shade Of Mine schrieb:

    ich verwende intrusive container zB dann, wenn ich allokationen sparen will - weil man 100% kontrolle über das resourcen management hat. das bedeutet aber auch, dass man eine auf die situation abgestimmte strategie verwenden muss.

    Was für Strategien verwendest du z.B. sonst noch?



  • Nexus schrieb:

    Shade Of Mine schrieb:

    Du machst einfach new und delete.

    Dann hat man aber vergleichsweise viele Allokationen, nämlich für jedes Element. Wo liegt der Vorteil gegenüber std::list ? Seit C++11 muss man ich schliesslich nicht mehr kopieren, sondern kann move oder emplace anwenden.

    Mir ist bewusst, dass man durch Intrusive Containers einige andere Vorteile hat, aber mich interessiert hier vor allem Speicherverwaltung...

    Du hast selber die Kontrolle. Das ist der Vorteil. std::list bietet zB sehr viel flexibilität weil man zB um ein Element aus der Liste zu entfernen es ja einfach eine Element-Pool Liste splicen kann und so die allokation/deallokation sparen kann.

    Aber stell dir eine map vor und du willst jetzt ein Element raus nehmen, weisst aber, dass du gleich wieder ein Element einfügen wirst. Bei einem intrusive container merke ich mir das Element einfach und ändere nur die Werte und häng es wieder in die Map. Das geht bei std::map nicht.

    Shade Of Mine schrieb:

    ich verwende intrusive container zB dann, wenn ich allokationen sparen will - weil man 100% kontrolle über das resourcen management hat. das bedeutet aber auch, dass man eine auf die situation abgestimmte strategie verwenden muss.

    Was für Strategien verwendest du z.B. sonst noch?

    Weil es zB vorhin aufkam: caches.

    Ich habe zB einen LRU Cache. Der besteht aus einer map und einer list. Ich weiß, dass ich genau N Elemente in diesem Cache halten will. Also allokiere ich 20 map und 20 list Elemente am Stück -> eine allokation.

    Wenn nun ein Element in den Cache wandern soll wird geprüft ob der Cache voll ist, wenn ja - letzte Element kicken. Dann einfach aus dem Pool 1 list und 1 map element nehmen und einfügen. Alles ohne allokation - nur mit Zeiger umbiegen.

    das ganze mit stl-containern ist nicht gut möglich. Man kann zwar aus der liste raus-splicen aber nicht aus der map. auch liegen die 20 listen Element nicht zwangsläufig am Stück hintereinander im Speicher.

    Hier ist die Strategie mit intrusive containern leicht: allokation im ctor und deallokation im dtor des caches.

    intrusive container sind nichts was man für allgemeine Situationen verwendet, sondern eben für solche speziellen Situationen wo man Allokationen genau kontrollieren will.

    Wenn du ein konkretes Beispiel hast, können wir gerne über Resource Management in diesem speziellen Fall reden. Allgemeingültig ist leider nur zB RAII. Aber spezielle Situationen muss man sich auch speziell ansehen.



  • @Nexus
    Mit intrusive Containern kannst du die Speicherverwaltung sehr unkompliziert und vor allem sehr flexibel selbst in die Hand nehmen.
    Mit klassischen Containern und Allokatoren geht es bestenfalls schlecht.

    Grössere Blöcke von Elementen auf einmal anfordern hat Shade ja schon geschrieben. Ein Element in mehrere Container auch.

    Was noch dazukommt:

    Und durch die externe Speicherverwaltung ist insert in die meisten intrusive Container no-throw, was auch in einigen Fällen sehr angenehm ist. Gerade wenn man das Element in mehreren Containern gleichzeitig verwalten will. Man spart sich dadurch den Undo-Code im Fehlerfall.



  • Ah okay, das macht Sinn, danke euch beiden.

    Konkretes Beispiel habe ich momentan keines, hat mich generell interessiert. Aber möglicherweise komme ich eines Tages darauf zurück 🙂


Anmelden zum Antworten