Ich wurde kürzlich auf die integrierten Funktionen von GCC für einige Speicherverwaltungsfunktionen der C-Bibliothek aufmerksam gemacht, insbesondere auf __builtin_malloc()
und damit verbundene Einbauten (siehe https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html). Nachdem ich etwas über __builtin_malloc()
erfahren hatte, fragte ich mich, wie es funktionieren könnte, Leistungsverbesserungen gegenüber den einfachen Bibliotheksroutinen zu bieten, die mit malloc()
vergleichbar sind.Welche Verbesserungen bietet GCC's `__builtin_malloc()` über plain `malloc()`?
Zum Beispiel, wenn die Funktion erfolgreich ist, hat es einen Block zu schaffen, die durch einen Aufruf Ebene free()
befreit werden kann, da der Zeiger kann durch einen Modul befreit werden, die falsch ohne __builtin_malloc()
oder __builtin_free()
aktiviert (oder bin kompiliert wurde ich Darüber und wenn __builtin_malloc()
verwendet wird, müssen die Builtins global verwendet werden?). Daher muss das zugeordnete Objekt etwas sein, das mit den Datenstrukturen verwaltet werden kann, die malloc()
und free()
betreffen.
Ich kann keine Details finden, wie __builtin_malloc()
funktioniert oder was es genau tut (ich bin kein Compiler-Entwickler, also spelunking durch GCC-Quellcode ist nicht in meinem Steuerhaus). In einigen einfachen Tests, in denen ich versucht habe, direkt __builtin_malloc()
aufzurufen, wird es einfach im Objektcode als Aufruf an plain malloc()
ausgegeben. Jedoch könnte es Feinheiten oder Plattformdetails geben, die ich in diesen einfachen Tests nicht bereitstelle.
Welche Arten von Leistungsverbesserungen können __builtin_malloc()
über einen Aufruf an Plain malloc()
bieten? Hat __builtin_malloc()
eine Abhängigkeit von den relativ komplexen Datenstrukturen, die glibcs malloc()
Implementierung verwendet? Oder umgekehrt, Glibs malloc()
/free()
Code haben, um mit Blöcken umzugehen, die von __builtin_malloc()
zugewiesen werden könnten?
Grundsätzlich, wie funktioniert es?
Interessante und nützliche Erklärung. Das wesentliche Merkmal der eingebauten Version ist also, dass sie dem Compiler ein bekanntes Verhalten garantieren kann, das es ermöglicht, sie weg zu optimieren und vielleicht auch andere Optimierungen zu erhalten ... –
@DanLenski So sehe ich es. Nach einer Reihe von Experimenten ist das einzige, was ich GCC dazu bringen kann, "Spezial" mit "__builtin_malloc" zu machen, es zu optimieren. Ich habe versucht, es "0" zu übergeben, aber das Ergebnis an eine andere (externe) Funktion übergeben verursacht einen Aufruf von "malloc" zu emittieren. –
Der Compiler weiß wahrscheinlich, dass das Ergebnis von __builtin_malloc nicht mit einem anderen Zeiger verknüpft ist. Nehmen wir an, Ihre Funktion hat int * p als Parameter und ruft int * q = malloc (sizeof int) auf; * q = 1; dann weiß der Compiler, dass diese Zuweisung * p nicht geändert hat. – gnasher729