Push-Nachrichten von MacTechNews.de
Würden Sie gerne aktuelle Nachrichten aus der Apple-Welt direkt über Push-Nachrichten erhalten?

Rosetta 2: Darum ist Apples „Notlösung“ für x86-Apps so schnell

Apples Umstieg auf die hauseigenen ARM-Chips begann vor zwei Jahren und ist mittlerweile fast abgeschlossen. Lediglich im Mac Pro arbeiten noch Intel-Prozessoren, alle anderen Desktops und Notebooks verfügen über eine M-CPU, in einigen werkelt sogar schon deren zweite Generation. Der fortschreitende Architekturwechsel macht sich naturgemäß auch bei den Apps bemerkbar, die meisten Anwendungen gibt es in nativen Ausführungen für Apple Silicon. Wer noch x86-Programme einsetzen muss, hat damit allerdings keine Probleme, denn Apple sorgt bekanntlich mit Rosetta 2 für umfassende Rückwärtskompatibilität von M-Macs.


Rosetta 2 übersetzt x86-Anweisungen in ARM-Code
Bemerkenswert an dem Tool, das den Übergang in die neue Mac-Ära so nahtlos wie möglich gestalten soll, ist dessen Performance. Der Entwickler Dougall Johnson hat jetzt ergründet, weshalb Rosetta 2 so schnell ist. Das Ergebnis seiner Untersuchung veröffentlichte er in einem längeren und aufschlussreichen Blog-Beitrag. Die Grundlage für die Geschwindigkeit legt Apple dadurch, dass es sich bei der „Notlösung“ für Intel-Apps bekanntermaßen nicht um einen reinen x86-Emulator handelt. Das in macOS enthaltene Tool übersetzt den ursprünglichen Code lediglich einmal in ARM-Instruktionen, und zwar vor dem ersten Start einer entsprechenden App. Dabei berücksichtigt Rosetta 2 auch Sprunganweisungen und Aufrufe. Nur wenn diese während der Laufzeit eines Programms unerwartet auf die Mitte einer x86-Instruktion verweisen, kommt während der Ausführung ein zusätzlicher Just-in-Time-Compiler zum Einsatz (JIT).

Optimierungen sorgen für Performance
Rosetta 2 enthält zudem weitere Optimierungen, welche sich positiv auf die Performance auswirken. Dazu gehört unter anderem ein spezielles RAM-Layout, bei dem übersetzter Binärcode hinter den noch im Original vorliegenden Teilen platziert wird. Das ermöglicht Johnson zufolge direkte Aufrufe der Runtime. Darüber hinaus unterstützt Apples Tool die in modernen Prozessoren, also auch in den M-Chips vorhandene „return address prediction“ und schreibt die x86-Instruktionen „CALL“ und „RET“ in die entsprechenden ARM-Anweisungen namens „BL“ und „RET“ um. Außerdem nutzt Rosetta 2 die „flag-manipulation extensions“ von ARM-Chips, um mit den Unterschieden zum Verhalten von Intel-CPUs effizient umgehen zu können. Weitere „Tricks“ setzt Apple im Zusammenhang mit dem Handling von Fließkommaoperationen sowie bei der Nutzung einer in den M-Prozessoren verwendeten Technik namens „total store ordering“ ein.

M-Chips enthalten eine spezielle Erweiterung
Die enorme Leistungsfähigkeit von Apple Silicon spielt bei der Performance von Rosetta 2 natürlich ebenfalls eine Rolle. Apple hat die hauseigenen SoCs zudem mit einer undokumentierten Erweiterung ausgestattet, welche die Umsetzung bestimmter Instruktionen und Register im Zusammenhang mit Additionen und Subtraktionen beschleunigt. Johnson zufolge dient dieser Ansatz dazu, die allergrößten Probleme bei der Übersetzung von Intel-Code in ARM-Anweisungen hardwareseitig anzugehen und somit im Zusammenspiel mit den anderen Maßnahmen für die bemerkenswerte Performance von Rosetta 2 zu sorgen.

Kommentare

athlonet10.11.22 18:13
Oder kurz gesagt: Die Leute bei Apple wissen was sie tun und haben alles richtig gemacht
+37
winfel10.11.22 19:53
"Rosetta 2 übersetzt ARM-Code in x86-Anweisungen".... Das ist doch falschrum.
+10
Dupondt10.11.22 20:09
winfel: Natürlich, danke für den Hinweis. Ist korrigiert.
+9
AppleUser2013
AppleUser201310.11.22 20:41
Hmm... Rosetta 2 übersetzt x64/amd64 Code in Arm.
x86 Code ist 32 Bit und es wäre mir neu, dass Rosetta 2 32 Bit Apps zum Laufen bringt...
0
Aulicus
Aulicus10.11.22 21:29
AppleUser2013
Hmm... Rosetta 2 übersetzt x64/amd64 Code in Arm.
x86 Code ist 32 Bit und es wäre mir neu, dass Rosetta 2 32 Bit Apps zum Laufen bringt...
+1
ssb
ssb10.11.22 21:32
Nun, das hatte ich bei Einführung der M-Chips schon gesagt. Der Intel-Code wird komplett disassembliert und in LLVM-IR Code übersetzt. Das ist am Anfang gerade mit den Status-Flags bei Intel sehr häßlicher und ineffizienter Code. Aber mit LLVM lässt sich das meiste weg optimieren (zB Status-Flags die nicht geprüft werden). Am Ende wird das ganze mit dem LLVM-Backend zu ARM Code übersetzt.
Das ganze geht natürlich nicht ganz so einfach und daher werden für Sprünge teils Exceptions verwendet und der Code in kleinere Blöcke zerlegt und hin und wieder muss dann einige Umwege gehen.

Nun, wir haben das schon gemacht um x64-Code für einen anderen Prozessor zu übersetzen - waren da aber technisch eingeschränkt (kein Speicherzugriff). Zum Spaß hatten wir Code, der mit MSVC auf Windows übersetzt wurde wieder zu x64 zurück übersetzt - der war dann ca. 10% effizienter.

Es gab früher auch mal ein OpenSource-Projekt „libcpu“, das aber irgendwann vereinsamt ist. Damals konnte man schon 6502 Code eines Commodore Rechners in x86 übersetzen.
+7
Schmitti8111.11.22 07:05
Auch wenn Apple keine 32-bit Mac Apps unterstützt, so scheint Rosetta 2 schon das ganze x86 Befehlsregister zu kennen. Das schließt wohl SSE2, x87 und 32-bit Befehle ein. Das ist schon ein bemerkenswertes Stück Software!
+5
lenn1
lenn111.11.22 07:28
Das sorgt aber auch leider dafür, dass sich Softwarehersteller auf die faule Haut legen.
Als Beispiel zB die Desktop WhatsApp Version ist immer noch Intel.
Und ich würd mal vorsichtig behaupten die haben genug Ressourcen & Kapazitäten das mal umzustellen.
+3
ssb
ssb11.11.22 08:55
Der x64 Befehlssatz (genauer gesagt die amd64 Erweiterung zum x86 und danach EMT64 von Intel) ist ja nicht gänzlich anders. Man kann ohne Probleme x86-Code auf x64 ausführen.
DIe meisten Befehle haben bei x64 einfach ein Prefix-Byte mit dem den Units in der CPU mitgeteilt wird, statt 32 Bit eben 64 zu verwenden. Wenn Immidiates in dem Befehl stehen, dann weiß der Decoder auch, dass der Befehl um 4 Bytes länger wird.
Das war bei der Umstellung von 8 auf 16 und dann 32 Bits nicht wirklich anders - nur dass damals noch Bits im Befehls-Byte frei waren. Aber es gab auch zuvor schon Prefix-Bytes für einige Erweiterungen.

Den Decoder hat das nicht einfacher gemacht, damit auch die Branch-Prediction, Instruction-Reordering etc. Deswegen kommt Intel nur mit hohem Energieaufwand in der Performanz weiter.

(Bei RISC sehen die Probleme anders aus - am Ende ist RISC aber leichter skalierbar).

Intel hatte mal eine echte 64-Bit CPUs gebaut (Itanium) der nicht 100% kompatibel zu x86 war. Wollte keiner. Dort war die Bequemlichkeit der Softwarehersteller dann zu groß.
0
StraightEdge89
StraightEdge8911.11.22 12:49
Wie machen das eigentlich andere Betriebssysteme? Wenn ein Linux aus einem PPC, X86 oder was auch immer Prozessor läuft müssen dann auch die Programme für jede Architektur vorliegen?
0
winfel11.11.22 13:08
StraightEdge89
Wie machen das eigentlich andere Betriebssysteme? Wenn ein Linux aus einem PPC, X86 oder was auch immer Prozessor läuft müssen dann auch die Programme für jede Architektur vorliegen?

Japp. Die werden für jede Architektur eigens compiliert.
+1
gfhfkgfhfk13.11.22 20:47
ssb
Den Decoder hat das nicht einfacher gemacht, damit auch die Branch-Prediction, Instruction-Reordering etc. Deswegen kommt Intel nur mit hohem Energieaufwand in der Performanz weiter.
Das Hauptproblem von CISC-CPUs sind die viel zu komplexen Adressierungsmodi, die von den CPUs unterstützt werden. Der zweite Aspekt sind die unterschiedlich langen Befehle. Beides zusammen erschwert enorm die spekulative Ausführung von Code und versaut die Branch Prediction.

Als historisches Beispiel: Motorola/FreeScale/NXP hat die 68k Familie für embedded Anwendungen weiter entwickelt (ColdFire), und die Cores vereinfacht. Keine BCD-Befehle mehr, Adressierungsmodi vereinfacht und FPU auf 64Bit reduziert. Wenn man das berücksichtigt läuft sogar alter 68k Code auf ColdFire.

Intel hat bei SSE und AVX die Designrichtlinie von RISC angewandt. Das ist wie RISC eine klassische Load-Store-Architektur und die Befehlslängen sind harmonisiert. Deshalb sagt Intel auch immer, dass man keinen x87 Code mehr nutzen soll, sondern nur noch SSE bzw. AVX Code. Die erzielte Rechenleistung ist auch absolut konkurrenzfähig und die CPUs sind auch effizient im Sinne von Flops/Watt, wenn sie AVX Code abarbeiten.

ARM kann noch nicht mithalten, da bisher vor ARMv8 die SIMD-Einheiten von ARM eher für Multimedia gedacht waren, und erst mit ARMv8 wurde eine allgemein nutzbare SIMD-Einheit mit nur 128Bit Breite verbindlich integriert (Neon). Einzig für das Fujitsu SuperComputer Projekt wurde eine spezielle ARMv8 CPU (A64FX) entwickelt, die bereits über SVE verfügt. Mit der neuen Architektur ARMv9 wird dann für Desktop/Server-CPUs SVE2 verbindlich werden. SVE/SVE2 erlaubt maximal 2048Bit breite SIMD Einheiten, und zwar so, dass der Befehlssatz sich nicht ändert, wenn die physikalische Verarbeitungsbreite sich ändert. D.h. man braucht nicht so wie bei Intel/AMD die Programme neu zu übersetzen, wenn eine CPU mit breiterer SIMD-Einheit kommt. Die A64FX CPU nutzt 512Bit breite Register, und liegt damit auf dem Niveau der Intel AVX512 Implementation. Bei AMD wird aktuell nur AVX512 mit 256Bit Registerbreite bearbeitet.
ssb
Intel hatte mal eine echte 64-Bit CPUs gebaut (Itanium) der nicht 100% kompatibel zu x86 war. Wollte keiner. Dort war die Bequemlichkeit der Softwarehersteller dann zu groß.
Itanium war gar nicht zu x86 kompatibel, das ist eine komplett andere CPU Architektur. Es war ein sehr spezielle RISC-Design mit erheblichen Schwächen (VLIW), die nie behoben werden konnten. Intel war mit Itanium nur in einem Aspekt sehr erfolgreich, es hat einige der RISC-Konkurrenz eliminiert. Dem Itanium Projekt fielen HP-PA, MIPS, Alpha zum Opfer. Einzig IBM war so schlau darauf zu verzichten, dass eigene RISC-Projekt (POWER/PowerPC/Power) nicht vorschnell zu beerdigen.

Nur der allererste Itanium (Merced) hat einen Hardwareemulator für x86 Code enthalten. D.h. bei Merced waren zwei Cores verbaut ein IA-64 und ein IA-32, dazu war der x86 Core nicht sonderlich schnell. Der wichtigste Projektpartner – HP – benötigte einen Emulator für PA-RISC. HP hat einen so guten Emulator (eigentlich wie bei Apple ein Recompiler) für PA-RISC entwickelt, dass man das Konzept auch für x86 Code nutzte. D.h. der Recompiler erzeugte schnelleren Code auf Merced als die x86 Einheit in der CPU, somit war die x86 Hardware überflüssig. Ab dem Itanium 2 wurde daher auf die x86 Fähigkeit bei IA-64 komplett verzichtet.

HP bot lange Zeit sowohl Workstations als auch Server mit Itanium an. Allerdings stellte sich schnell heraus, dass die Kunden auf Itanium entweder HP-UX oder Linux nutzen. Der Bedarf an Windows NT war eher minimal, und nur für einige spezielle MS SQL Installationen wurde Windows auf Itanium genutzt. Hinzu kam, dass AMD die Erweiterung von x86 zu x86-64 vorstellte, und das bei der überragenden Mehrheit im Markt sehr viel besser ankam, als ein vermurkster RISC-Prozessor mit überhöhtem Preis.
+3
fleissbildchen15.11.22 11:05
gfhfkgfhfk
Wow - danke für den ausführlichen Einblick!
0

Kommentieren

Sie müssen sich einloggen, um die News kommentieren zu können.