Site Overlay

Stapelbasierte Speicherzuweisung

Da die Daten auf eine Last-in-First-Out-Weise hinzugefügt und entfernt werden, ist die stapelbasierte Speicherzuweisung sehr einfach und in der Regel viel schneller als die heapbasierte Speicherzuweisung (auch als dynamische Speicherzuweisung bezeichnet) typischerweise über malloc zugewiesen. Ein weiteres Merkmal ist, dass der Speicher auf dem Stapel beim Beenden der Funktion automatisch und sehr effizient zurückgewonnen wird, was für den Programmierer praktisch sein kann, wenn die Daten nicht mehr benötigt werden., (Dasselbe gilt für longjmp, wenn es an einen Punkt verschoben wurde, bevor der Aufruf von alloca.), Wenn jedoch, müssen die Daten aufbewahrt werden, in irgendeiner form, dann muss es kopiert werden vom Stapel auf den heap, bevor die Funktion beendet wird. Daher eignet sich die stapelbasierte Zuordnung für temporäre Daten oder Daten, die nach dem Beenden der aktuellen Funktion nicht mehr benötigt werden.

Die zugewiesene Stapelgröße eines Threads kann auf einigen kleinen CPUs nur wenige Bytes betragen. Das Zuweisen von mehr Speicher auf dem Stapel als verfügbar kann zu einem Absturz aufgrund eines Stapelüberlaufs führen., Dies ist auch der Grund, warum Funktionen, die alloca verwenden, normalerweise daran gehindert werden, inline zu sein: Sollte eine solche Funktion in eine Schleife eingebunden werden, würde der Aufrufer unter einem unerwarteten Anstieg der Stapelnutzung leiden, was einen Überlauf viel wahrscheinlicher macht.

Stack-basierte Zuordnung kann auch kleinere Leistungsprobleme verursachen: Sie führt zu Stack-Frames variabler Größe, sodass sowohl Stack-als auch Frame-Zeiger verwaltet werden müssen (bei Stack-Frames fester Größe ist einer davon redundant)., Dies ist normalerweise viel kostengünstiger als der Aufruf von malloc und free. Insbesondere wenn die aktuelle Funktion sowohl Aufrufe von alloca als auch Blöcke enthält, die lokale Daten variabler Länge enthalten, tritt ein Konflikt zwischen den Versuchen von alloca auf, den aktuellen Stapelrahmen zu erhöhen, bis die aktuelle Funktion beendet wird, und der Notwendigkeit des Compilers, lokale Variablen variabler Länge an derselben Stelle im Stapelrahmen zu platzieren., Dieser Konflikt wird normalerweise gelöst, indem für jeden Aufruf von alloca eine separate Heapspeicherkette erstellt wird (siehe: https://code.woboq.org/gcc/libiberty/alloca.c.html). Die Kette zeichnet die Stapeltiefe auf, bei der jede Zuweisung erfolgt, nachfolgende Aufrufe von alloca in jeder Funktion trimmen diese Kette auf die aktuelle Stapeltiefe, um schließlich (aber nicht sofort) Speicher in dieser Kette freizugeben. Ein Aufruf von alloca mit einem Argument von Null kann auch verwendet werden, um die Freigabe von Speicher auszulösen, ohne dass ein solcher Speicher mehr zugewiesen wird., Als Folge dieses Konflikts zwischen alloca und lokalem Variablenspeicher ist die Verwendung von alloca möglicherweise nicht effizienter als die Verwendung von malloc.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.