Warum ist der Mac-ABI erfordert 16-byte-stack-Ausrichtung für x86-32?
Kann ich verstehen, diese Anforderung für die alten PPC-RISC-Systemen und auch für x86-64, sondern für die alte erprobte und wahre x86? In diesem Fall wird der Stapel ausgerichtet werden muss auf 4-byte-Grenzen nur. Ja, einige der MMX/SSE Anweisungen erforderlich 16byte Ausrichtungen, aber wenn, dass ist eine Anforderung von den angerufenen, dann sollte Sie für die Zuordnungen korrekt sind. Warum Last jeder Anrufer mit dieser zusätzlichen Anforderung? Dies kann tatsächlich dazu führen, dass einige Tropfen in die Leistung, da jeder call-site verwalten müssen diese Anforderung. Bin ich etwas fehlt?
Update: Nach einigen weiteren Untersuchung dieser und einiger Beratung mit einigen internen Kolleginnen und Kollegen, ich habe einige Theorien darüber:
- Konsistenz zwischen der PPC -, x86-und x64-version des OS
- Es scheint, dass die GCC-codegen jetzt konsequent wird eine sub esp,xxx und dann "mov"s die Daten auf den Stapel, anstatt einfach ein "push" - Anweisung. Dies könnte sogar schneller sein auf einige hardware.
- Während dies erschwert die call sites ein wenig, es gibt sehr wenig zusätzlichen overhead bei Verwendung des Standard "cdecl" - convention, wo der Aufrufer bereinigt den stack.
Habe ich ein Problem mit dem letzten Punkt, ist, dass für den Aufruf-Konventionen, die sich auf die aufgerufene Reinigung der stack, die oben genannten Anforderungen wirklich "uglifies" die codegen. Zum Beispiel, was manche compiler beschlossen, die eine schnellere register-basierten Aufruf Stil für seine eigene interne Verwendung (ie-code, der ist nicht dazu da, genannt zu werden, die aus anderen Sprachen oder Quellen)? Diese stack-alignment-Sache verneinen könnte, einige der performance-Gewinne erreicht durch die übergabe einiger Parameter in Registern.
Update: bisher die einzige wirkliche Antworten wurden Konsistenz, aber für mich ist das eine etwas zu einfache Antwort. Ich habe über 20 Jahre Erfahrung mit der x86-Architektur, und wenn die Konsistenz, nicht die Leistung, oder etwas anderes konkretes ist, ist wirklich der Grund, dann ich respektvoll vorschlagen, dass ist ein bisschen naiv für die Entwickler, um es erfordern. Sie ignorieren fast drei Jahrzehnten tools und support. Vor allem, wenn Sie erwarten, dass Anbieter von tools, um schnell und einfach an Ihre Werkzeuge für Ihre Plattform (vielleicht auch nicht... es ist Apple...), ohne zu springen durch mehrere scheinbar unnötige Reifen.
Gebe ich dieses Thema an einem anderen Tag oder so schließen Sie es dann...
Verwandte
- Nicht-API. ABI (Application Binär - Schnittstelle.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aus der "Intel®64 and IA-32 Architectures Optimization Reference Manual", Kapitel 4.4.2:
"Für die beste Leistung, die Streaming-SIMD-Erweiterungen und Streaming SIMD Extensions 2 erfordern es, dass Ihre Speicher-Operanden ausgerichtet werden, um 16-byte-Grenzen. Nicht ausgerichtete Daten kann zu erheblichen Leistungseinbußen im Vergleich zu Daten ausgerichtet."
Anhang D:
"Es ist wichtig, um sicherzustellen, dass der stack frame ist ausgerichtet auf eine 16-byte-Grenze, die auf Funktion Eintrag zu halten, local __m128 Daten, Parameter und XMM register spill Standorte ausgerichtet, während ein Funktions-Aufruf."
http://www.intel.com/Assets/PDF/manual/248966.pdf
Ich bin mir nicht sicher, wie ich haben keine erste-hand-Beweis, aber ich glaube, der Grund ist SSE. SSW ist viel schneller, wenn Ihre Puffer sind bereits ausgerichtet auf eine 16-Byte-Grenze (movps vs movups), und x86 hat mindestens sse2-Unterstützung für mac os x. Es kann gesorgt werden, indem der Benutzer der Anwendung, aber der Preis ist ziemlich bedeutend. Wenn die Gesamtkosten für die es Pflicht in der ABI ist nicht allzu bedeutend, es kann es Wert. SSE wird durchaus genutzt um sich greifenden in mac os X: beschleunigen, Rahmen, etc...
Ist, glaube ich, zu halten, ihn mit der x86-64-ABI.
Beachten Sie zunächst, dass der 16-Byte-alignment ist eine Ausnahme eingeführt von Apple, um die System-V-IA-32-ABI.
Die stack-Ausrichtung ist nur nötig, wenn der aufrufende system funktioniert, denn viele system-Bibliotheken verwenden, SSE oder Altivec-Erweiterungen, bei denen der 16-Byte-Ausrichtung. Ich fand einen expliziten Verweis in der libgmalloc MANN Seite.
Können Sie perfekt mit Ihren stack-frame, wie Sie wollen, aber wenn Sie versuchen, rufen eine system-Funktion mit einem Schiefen Stapel, werden Sie am Ende mit einem misaligned_stack_error Nachricht.
Edit:
Für den Datensatz, können Sie loswerden der alignment-Probleme beim kompilieren mit GCC mithilfe der mstack-neu auszurichten option.
Dies ist ein Effizienz-Problem.
Sicherstellen, dass der Stapel 16-byte-ausgerichtet, in jeder Funktion verwendet die neue SSE-Instruktionen bringt eine Menge overhead mit diesen Anweisungen, eine effektive Senkung der Leistung.
Auf der anderen Seite, halten die Stapel 16-byte-ausgerichtet auf alle Zeiten sichergestellt, dass Sie verwenden können, SSE-Anweisungen frei mit keine Leistungseinbußen. Es gibt keine Kosten, um diese Kosten (gemessen in der Anleitung zumindest). Es nur um das ändern einer Konstanten im Prolog der Funktion.
Verschwenden stack-Speicher ist Billig, es ist wohl der heißeste Teil des cache.
Meine Vermutung ist, dass Apple glaubt einfach jeder nutzt XCode (gcc), die richtet den Stapel für Sie. So dass der Stapel ausgerichtet werden, damit der kernel nicht haben, ist nur eine Mikro-Optimierung.
Während ich kann nicht wirklich die Antwort auf Ihre Frage, WARUM, finden Sie die Handbücher unter der folgenden Website hilfreich sein:
http://www.agner.org/optimize/
Bezüglich der ABI, haben einen Blick besonders an:
http://www.agner.org/optimize/calling_conventions.pdf
Hoffe, das ist nützlich.
Hmm, nicht OS X ABI auch lustig RISC wie Dinge wie, vorbei an kleinen structs in Registern?
So, dass die Punkte, um die Konsistenz mit anderen Plattformen Theorie.
Kommen Sie, daran zu denken, die FreeBSD-syscall-api richtet außerdem 64-bit-Werte. (wie z.B. lseek und mmap)
Um die Konsistenz zu wahren, der im kernel. Dies ermöglicht es der gleiche kernel gebootet werden, die auf mehreren Architekturen ohne modicfication.
Nicht sicher, warum, niemand als die Möglichkeit der einfachen Portabilität von älteren PowerPC-basierten Plattform?
Lesen:
http://developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/LowLevelABI/100-32-bit_PowerPC_Function_Calling_Conventions/32bitPowerPC.html#//apple_ref/doc/uid/TP40002438-SW20
Und dann gezoomt "32-bit-PowerPC-Funktion Calling Conventions" und schließlich:
Im Blick auf den älteren PowerPC-basierten hintergrund von OSX, Portabilität ist ein wichtiger Aspekt - es diktiert, mit der Konvention den ganzen Weg zurück nach AIX XLC compiler. Wenn Sie denken, in Bezug auf die Notwendigkeit, sicherzustellen, dass alle tools und Anwendungen zusammen arbeiten, mit minimalen Nacharbeiten, ich denke, es ist wichtig, zu bleiben, um die gleichen legacy-ABI so weit wie möglich.
Gibt die Philosophie, und Lesen weiter in der Regel explizit erwähnt ("Prolog und Epilog"):