Frage

Ich suche einen Selbst Defragmentieren Speicher-Manager zu schreiben, wodurch ein einfacher Inkrementierung Haufen allocator in Kombination mit einem einfachen Verdichtungs Defragmentierer verwendet wird.

Das grobe Schema wäre Blöcke zuzuordnen bei der niedrigsten Speicheradresse beginnend nach oben gehen und gehalts Informationen auf der höchsten Speicheradresse beginnend arbeitet nach unten.

Der Speichermanager würde passieren zurück Smart Pointer - Boost des intrusive_ptr der scheint die naheliegendste der Buchführung structs, die dann würde sich der tatsächliche Speicherblock zeigen somit eine Dereferenzierungsebene geben, so dass die Blöcke um leicht bewegt werden kann.

Die defragmentierer würden die Halde ab ‚Generation‘ Lesezeichen kompaktieren nach unten um den Prozess zu beschleunigen, und nur eine feste Größe des Speichers zu einem Zeitpunkt defragmentieren. Raw Zeiger auf die Blöcke würden sich bis zum nächsten defrag Pass gültig sein und so um bis zu einem Zeitpunkt der Verbesserung der Leistung frei weitergegeben werden können.

Die spezifische Anwendung hierfür ist, Konsolen-Spiel-Programmierung und so am Anfang oder Ende eines jedes Rahmens ein defrag Pass relativ sicher durchgeführt werden kann.

Also meine Frage jemand wird diese Art von Zuordnungsschema in Kombination mit STL verwendet hat, würde es STL nur völlig sprengen auseinander, wie ich vermute. Ich kann std :: list Arbeiten an der intrusive_ptr Ebene aber was über die Zuteilung der stl Liste Knoten selbst ist es trotzdem die nächsten / vorherigen Zeiger außer Kraft zu setzen intrusive_ptr ist, sich selbst zu sein, oder bin ich nur gehen zu müssen, haben Standard Haufen allocator an der Seite dieses dynamischere ein.

War es hilfreich?

Lösung

Wenn Sie vorhaben, in Erinnerung bewegte Objekte herum werden, dann können Sie dies ganz allgemein nicht. Sie werden nur in der Lage sein, dies mit Objekten zu tun, dass wissen , dass sie verschoben werden könnten. Sie werden auch einen Verriegelungsmechanismus benötigen. Wenn eine Funktion auf einem Objekt aufgerufen wird, dann kann es nicht verschoben werden.

Der Grund dafür ist, dass die gesamte C ++ Modell auf Objekte beruht auf Fixpunkte im Speicher sitzt, so dass, wenn ein Thread wurde eine Methode für ein Objekt aufrufen, wurde dieser Thread pausiert und das Objekt bewegt, Katastrophe treffen würde, wenn der Faden wieder aufgenommen.

Jedes Objekt, das einen rohen Speicherzeiger auf ein anderes Objekt gehalten, die (einschließlich einem Teilobjekt selbst) bewegt werden könnten, würde nicht funktionieren.

Ein solches Speicherverwaltungsschema kann funktionieren, aber man muss sehr vorsichtig sein. Sie müssen über die Implementierung Griffe streng sein, und die Griff-> Zeigerverriegelungs Semantik.

Für STL-Container können Sie den allocator anpassen, aber es muss noch festen rohen Speicherzeiger zurück. Sie können eine Adresse zurück, die sich bewegen könnte. Aus diesem Grund, wenn Sie STL-Container verwenden, müssen sie Behälter mit Griffen sein, und die Knoten werden sich gewöhnlichen dynamisch zugewiesenen Speicher sein. Sie können feststellen, dass Sie zu viel in Overhead in dem Griff indirection und immer noch Probleme bei der Fragmentierung der Griff Sammlungen als Sie mithilfe von STL gewinnen.

Mit Containern, die Ihre Griffe direkt verstehen, könnte der einzige Weg nach vorne sein, und selbst dann kann es noch eine Menge Overhead im Vergleich zu einer C ++ Anwendung, die im Speicher festgelegt traditionelle Objekte verwendet.

Andere Tipps

STL-Container implementiert nackte Zeiger verwenden.

Sie können eine benutzerdefinierte allocator angeben, wenn Sie sie instanziiert (damit sie sie initialisieren ihre Zeiger Ihre allocator verwenden), aber (da die zugewiesenen Werte in nackten Zeiger gespeichert sind) Sie wissen nicht, wo diese Zeiger sind, und damit Sie kann sie später nicht mehr ändern.

Stattdessen Sie sich anschauen sollten eine Teilmenge der STL Implementierung selbst. Ihre Versionen der STL-Container könnte dann mit einem verwalteten Zeiger implementiert werden

Eine alternative Technik, die ziemlich gut bekannt ist, ist die Buddy-System rel="nofollow. Sie sollten sich, dass für zusätzliche Inspiration einen Blick darauf werfen.

Wenn dies für die Konsolenspieleprogrammierung ist es ist viel einfacher, un-scoped dynamische Speicherzuweisung zur Laufzeit zu verbieten. Und beim Start, aber das ist ein bisschen schwierig zu erreichen.

auf diese Meine Meinung ist, dass, wenn Angst vor der Fragmentierung sein, das heißt, Sie jonglieren um mit Datenstücken, die einen großen Anteil an der Speicher sind, und durch diese Tugend allein, nicht viele von ihnen haben kann. Wissen Sie schon, was diese sein? Vielleicht wäre es besser, ein Niveau Schritt nach unten und präzisen Entscheidungen zu treffen, damit weniger auf dem anderen Code zu behindern und die allgemeinen Leistung Ihrer Anwendung?

Eine Liste ist ein besonders schlechtes Beispiel in einen Defragmentieren Speichermanager zu setzen, weil es ein paar kleine Stücke ist, wie die meisten anderen STL-Datenstrukturen sind. Wenn Sie dies tun, wird es alle Arten von offensichtlich schlechte Auswirkungen haben - einschließlich der Leistung Ihres Defragmentierer nach unten geht, auch die Indirekt Kosten usw. Die einzigen Strukturen, wo es Sinn macht IMO sind contigious diejenigen - Array, deque, Haupt Batzen hashtable , diese Dinge, und nur über eine gewisse Größe, und erst, nachdem sie nicht gonna Größe verändert länger werden. Diese Art der Dinge nennen, wieder für spezifische Lösungen anstelle von generischen.

Kommentar zurück, wie es sich herausstellt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top