Ich bin auf der Suche nach einem Heap-Allocation-Algorithmus in C für einen Speicher-Constrained-Mikrocontroller zu implementieren. Ich habe meine Suche auf 2 Optionen beschränkt, die mir bekannt sind, aber ich bin sehr offen für Vorschläge, und ich suche Rat oder Kommentare von jemandem mit Erfahrung in diesem Bereich.Fragmentierung-resistente Microcontroller Heap-Algorithmus
Meine Anforderungen:
-Geschwindigkeit zählt auf jeden Fall, aber es ist zweitrangig.
-Timing Determinismus ist nicht wichtig - jeder Teil des Codes, der deterministische Worst-Case-Timing erfordert, hat seine eigene Zuweisungsmethode.
-Die wichtigste Voraussetzung ist Fragmentierung Immunität. Auf dem Gerät wird eine Lua-Skript-Engine ausgeführt, die eine Reihe von Zuweisungsgrößen erfordert (schwer auf den 32-Byte-Blöcken). Die Hauptanforderung ist, dass dieses Gerät für eine lange Zeit ausgeführt wird, ohne seinen Heap in einen unbrauchbaren Zustand zu versetzen. Hinweis
auch:
-Für Referenz, wir sprechen über ein Cortex-M und PIC32-Teile, mit Speicher im Bereich von 128K und 16MB oder Speicher (mit einem Schwerpunkt auf dem unteren Ende).
-Ich möchte nicht den Heap des Compilers verwenden, weil 1) Ich möchte konsistente Leistung über alle Compiler und 2) ihre Implementierungen sind in der Regel sehr einfach und sind die gleichen oder schlechter für die Fragmentierung.
-Double indirekte Optionen sind out wegen der großen Lua-Code-Basis, die ich nicht grundlegend ändern und revalidate wollen.
Meine Begünstigungs Ansätze So Far:
1) Haben Sie einen binären Kumpel allocator und Speichernutzungseffizienz opfern (Rundung auf eine Leistung von 2 Größe nach oben). -dies würde (wie ich es verstehe) einen binären Baum für jede Reihenfolge/Ablage erfordern, um freie Knoten zu speichern, sortiert nach Speicheradresse für einen schnellen Buddy-Block-Lookup zum erneuten Speichern.
2) Zwei Binärbäume für freie Blöcke haben, eine sortiert nach Größe und eine nach Speicheradresse sortiert. (Alle binären Baumverknüpfungen sind im Block selbst gespeichert.) -allocation würde am besten mit einem Nachschlagen in der Tabelle nach Größe und dann entfernen Sie diesen Block aus dem anderen Baum durch Adresse -deallocation würde benachbarte Blöcke nach Adresse für suchen wiedererhalten
-Beide Algorithmen würden auch erfordern, eine Zuweisungsgröße vor dem Start des zugewiesenen Blocks zu speichern, und Blöcke gehen als eine Potenz von 2 minus 4 (oder 8 abhängig von der Ausrichtung). (Es sei denn, sie speichern einen Binärbaum an anderer Stelle, um Zuordnungen nach Speicheradresse zu verfolgen, was ich nicht für eine gute Option halte)
- Beide Algorithmen erfordern höhenausgleichenden Binärcode.
-Algorithmus 2 hat nicht die Anforderung, Speicher durch Aufrunden auf eine Zweierpotenz zu verschwenden.
- In jedem Fall werde ich wahrscheinlich eine feste Bank von 32-Byte-Blöcken durch verschachtelte Bitfelder zugewiesen haben, um Blöcke dieser Größe oder kleiner zu entladen, die gegen externe Fragmentierung immun wären.
Meine Fragen:
-Ist es einen Grund, warum Ansatz 1 mehr immun gegen Fragmentierung als Ansatz wäre 2?
- Gibt es irgendwelche Alternativen, die ich vermisse, die den Anforderungen entsprechen könnten?
Das Buddy-System muss keinen Binärbaum verwenden, um den möglichen Buddy eines Blocks zu finden, wenn er freigegeben wird. Sie können die Adresse eines Kontakts aus der Adresse des ursprünglichen Blocks ermitteln. Dann überprüfen Sie ein bisschen, ob dieser Freund frei ist oder benutzt wird. Sie können dieses Bit an den Anfang des Bereichs setzen - also würden Sie nicht wirklich 32 Bytes bekommen, sondern vielleicht 31 verwendbare Bytes. Sie können dies ändern, indem Sie ein separates Bitmap für free/used verwenden. Knuth beschreibt eine Version, die Tag-Bits für freie/gebrauchte verwendet – mcdowella
Yah, ich dachte gerade darüber nach. Ich denke, 2GB Blockgröße ist wahrscheinlich gut genug :) Was ich denke, würde funktionieren, um den Binär-Baum für freie Knoten loszuwerden wäre, die freien Knoten jedes bin/order in einer doppelt verknüpften zirkulären Liste zu speichern, und nur die Buddy's verwenden Zeiger, um den nächsten und vorherigen Knoten zu verketten (und den Kopf ptr um einen Knoten voranzutreiben, wenn er auf den entfernten Knoten zeigt). Auf diese Weise gibt es überhaupt keine Suche, um einen kostenlosen Kumpel zu finden und zu entfernen. Also keine Binärbaumimplementierung. Gedanken? –
müssen Sie wirklich zuordnen? Eingebettete Systeme wie diese weisen in der Regel keine festen Strukturen zu (außer natürlich Stack, auf den Sie achten müssen). fügt etwas zu viel Risiko zu etwas hinzu, das felsenfest sein soll. –