2 Punkte von GN⁺ 4 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • OxCaml, eine OCaml-Obermenge von Jane Street, ermöglicht es mit [@zero_alloc], dem Compiler für einen ganzen Funktionsaufrufbaum ein Verbot von Heap-Allokationen zu deklarieren
  • Entsteht auf dem deklarierten Aufrufpfad dennoch eine Allokation, wird dies sofort durch einen Kompilierfehler sichtbar, wodurch sich Regressionen schneller verhindern lassen als mit späterer Suche per Profiler
  • In C, C++, Java, Go, C#, Rust, Zig, OCaml usw. steht meist der Ansatz im Mittelpunkt, Allokationen auf Hot Paths mit einem Profiler zu finden und zu reduzieren
  • Code auf Hot Paths kann schon durch kleine Änderungen wieder Allokationen erzeugen; vergisst man den Kontext der bisherigen Optimierung, muss man dieselbe Untersuchung erneut durchführen
  • Auch Konventionen zur Weitergabe von Allocators in Zig oder Teilen des modernen Rust helfen, doch eine Compiler-Prüfung ist eine direktere Absicherung als bloße Konventionen

Was [@zero_alloc] an der Allokationsverwaltung verändert

  • OxCaml ist eine OCaml-Obermenge von Jane Street und unterstützt Zusicherungen, dass Funktionen nichts auf dem Heap allokieren
  • Fügt man einer Funktion [@zero_alloc] hinzu, prüft der Compiler nicht nur diese Funktion, sondern den gesamten darunterliegenden Aufrufbaum auf Heap-Allokationen
  • Wenn innerhalb des Aufrufbaums eine Allokation auftritt, schlägt der Build fehl und der Compiler meldet die Allokation
  • Es wäre zwar denkbar, mit statischer Analyse ähnliche Prüfungen zu bauen, aber unter Mainstream-Sprachen sind Sprachen selten, die so etwas anhand erzeugter Zusammenfassungen direkt in den Compiler eingebaut haben

Unterschied zum profilerzentrierten Ansatz

  • In anderen Sprachen werden Allokationen typischerweise erst mit einem Profiler gefunden und dann reduziert oder entfernt, besonders innerhalb von Schleifen, die millionenfach ausgeführt werden
  • C, C++, Java, Go, C#, Rust, Zig und OCaml werden als Beispiele für diesen profilerzentrierten Ansatz genannt
  • Schon eine geänderte Zeile auf einem Hot Path kann wieder Allokationen einführen, und um die Ursache zu finden, muss man erneut zum Profiler greifen
  • In Zig oder Teilen des modernen Rust lassen sich Regressionen reduzieren, indem kein Allocator an Funktionen übergeben wird, doch das beruht auf Konventionen
  • Der Unterschied von [@zero_alloc] besteht darin, dass nicht nachträgliche Analyse oder Teamregeln greifen, sondern der Compiler bereits beim Build Allokationsregressionen blockiert

1 Kommentare

 
GN⁺ 4 시간 전
Kommentare auf Lobste.rs
  • Ich habe verstanden, dass man in Zig einen Allocator als Funktionsargument übergibt, damit Funktionen, die keinen Allocator als Argument erhalten, keine Heap-Allokationen durchführen können. Stimmt das?
    Wenn „Konventionen können ignoriert werden“ wirklich zutrifft, scheint das der Absicht zu widersprechen.

    • Stimmt, letztlich ist es nur eine Konvention.
      Man kann auch innerhalb einer Funktion einen neuen Allocator erzeugen, genauso wie außerhalb.
  • Gift Link: https://theconsensus.dev/p/2026/…

  • In Rust nur core zu verwenden, ist ebenfalls eine Möglichkeit, Allokationen zu vermeiden.

    • „Allokationen vermeiden“ ist nur ein Teil der Geschichte.
      Dieser Ansatz läuft letztlich eher auf „kontrolliere deine Abhängigkeiten“ oder „prüfe den gesamten Call Graph manuell“ hinaus.
      Der Fokus des Artikels liegt darauf, wie Tools wie ein Compiler bestimmte Eigenschaften statisch erzwingen und einen Workflow bereitstellen können, mit dem man produktiv die Stellen findet, an denen diese Eigenschaft verletzt wird.
  • D hat @nogc; danach geht es darum, nur noch direkt kontrollierbare Abstraktionen mit klaren Allokationsmustern zu verwenden.

  • Weil die Fähigkeit verloren gegangen ist, Artikeltitel beschreibend zu formulieren, noch als Ergänzung: Kernpunkt ist eine Funktion, bei der man eine Funktion mit [@zero_alloc] annotiert und der Compiler das Programm ablehnt, wenn der Call Tree dieser Funktion den Heap berührt.

  • Ich frage mich, ob sich so ein Ansatz auch auf verschiedene Bedingungen wie „wirft keine Ausnahmen und panickt nicht“, „keine Locks“ oder „terminiert immer“ anwenden ließe.