Anzeige schließen

Mike Ash gewidmet auf seinem Blog die praktischen Auswirkungen des Wechsels zur 64-Bit-Architektur im iPhone 5S. Dieser Artikel basiert auf seinen Erkenntnissen.

Der Grund für diesen Text liegt vor allem darin, dass viele Fehlinformationen darüber verbreitet werden, was das neue iPhone 5s mit 64-Bit-ARM-Prozessor tatsächlich für Benutzer und Markt bedeutet. Hier werden wir versuchen, objektive Informationen über die Leistung, Möglichkeiten und Auswirkungen dieses Übergangs für Entwickler bereitzustellen.

„64 Bit“

Es gibt zwei Teile eines Prozessors, auf die sich die Bezeichnung „X-Bit“ beziehen kann – die Breite der Ganzzahlregister und die Breite der Zeiger. Glücklicherweise sind diese Breiten bei den meisten modernen Prozessoren gleich, sodass dies im Fall des A7 64-Bit-Integer-Register und 64-Bit-Zeiger bedeutet.

Es ist jedoch ebenso wichtig darauf hinzuweisen, was „64bit“ NICHT bedeutet: Größe der physischen RAM-Adresse. Die Anzahl der Bits für die Kommunikation mit dem RAM (also die Menge an RAM, die ein Gerät unterstützen kann) hängt nicht von der Anzahl der CPU-Bits ab. ARM-Prozessoren haben Adressen zwischen 26 und 40 Bit und können unabhängig vom Rest des Systems geändert werden.

  • Datenbusgröße. Die vom RAM oder Pufferspeicher empfangene Datenmenge ist ebenfalls unabhängig von diesem Faktor. Einzelne Prozessoranweisungen fordern möglicherweise unterschiedliche Datenmengen an, sie werden jedoch entweder in Blöcken gesendet oder mehr als nötig aus dem Speicher empfangen. Es kommt auf die Größe des Datenquantums an. Das iPhone 5 empfängt bereits Daten aus dem Speicher in 64-Bit-Quanten (und verfügt über einen 32-Bit-Prozessor), und wir können auf Größen bis zu 192 Bit stoßen.
  • Alles, was mit Gleitkomma zu tun hat. Die Größe solcher Register (FPU) ist wiederum unabhängig von der internen Funktionsweise des Prozessors. ARM verwendet 64-Bit-FPU bereits vor ARM64 (64-Bit-ARM-Prozessor).

Allgemeine Vor- und Nachteile

Wenn wir ansonsten identische 32-Bit- und 64-Bit-Architekturen vergleichen, unterscheiden sie sich im Allgemeinen nicht so sehr. Dies ist einer der Gründe für die allgemeine Verwirrung der Öffentlichkeit, die nach einem Grund sucht, warum Apple auch bei Mobilgeräten auf 64-Bit umsteigt. Allerdings hängt alles von den spezifischen Parametern des A7 (ARM64)-Prozessors und der Art und Weise ab, wie Apple ihn verwendet, und nicht nur von der Tatsache, dass der Prozessor über eine 64-Bit-Architektur verfügt.

Wenn wir uns jedoch noch die Unterschiede zwischen diesen beiden Architekturen ansehen, werden wir mehrere Unterschiede feststellen. Das Offensichtliche ist, dass 64-Bit-Ganzzahlregister 64-Bit-Ganzzahlen effizienter verarbeiten können. Schon vorher war es möglich, mit ihnen auf 32-Bit-Prozessoren zu arbeiten, allerdings bedeutete dies meist, dass man sie in 32-Bit lange Stücke aufteilte, was zu langsameren Berechnungen führte. Daher kann ein 64-Bit-Prozessor im Allgemeinen mit 64-Bit-Typen genauso schnell rechnen wie mit 32-Bit-Typen. Dies bedeutet, dass Anwendungen, die im Allgemeinen 64-Bit-Typen verwenden, auf einem 64-Bit-Prozessor viel schneller ausgeführt werden können.

Obwohl 64 Bit keinen Einfluss auf die Gesamtmenge an RAM hat, die der Prozessor nutzen kann, kann es die Arbeit mit großen RAM-Blöcken in einem Programm erleichtern. Jedes einzelne Programm, das auf einem 32-Bit-Prozessor läuft, verfügt nur über etwa 4 GB Adressraum. Wenn man berücksichtigt, dass das Betriebssystem und die Standardbibliotheken etwas beanspruchen, bleiben dem Programm etwa 1–3 GB für die Anwendungsnutzung. Wenn ein 32-Bit-System jedoch über mehr als 4 GB RAM verfügt, ist die Nutzung dieses Speichers etwas komplizierter. Wir müssen das Betriebssystem dazu zwingen, diese größeren Speicherblöcke für unser Programm abzubilden (Speichervirtualisierung), oder wir können das Programm in mehrere Prozesse aufteilen (wobei jeder Prozess wiederum theoretisch 4 GB Speicher für die direkte Adressierung zur Verfügung hat).

Allerdings sind diese „Hacks“ so schwierig und langsam, dass nur wenige Anwendungen sie nutzen. In der Praxis nutzt jedes Programm auf einem 32-Bit-Prozessor nur 1–3 GB Speicher, und mehr verfügbarer RAM kann verwendet werden, um mehrere Programme gleichzeitig auszuführen oder diesen Speicher als Puffer (Caching) zu verwenden. Diese Verwendungsmöglichkeiten sind praktisch, aber wir möchten, dass jedes Programm problemlos Speicherblöcke von mehr als 4 GB nutzen kann.

Nun kommen wir zu der häufigen (eigentlich falschen) Behauptung, dass eine 4-Bit-Architektur ohne mehr als 64 GB Speicher nutzlos sei. Ein größerer Adressraum ist auch auf einem System mit weniger Speicher sinnvoll. Speicherzuordnungsdateien sind ein praktisches Tool, bei dem ein Teil des Dateiinhalts logisch mit dem Speicher des Prozesses verknüpft wird, ohne dass die gesamte Datei in den Speicher geladen werden muss. So kann das System beispielsweise nach und nach große Dateien verarbeiten, die um ein Vielfaches größer sind als die RAM-Kapazität. Auf einem 32-Bit-System können solch große Dateien nicht zuverlässig dem Speicher zugeordnet werden, wohingegen dies auf einem 64-Bit-System dank des viel größeren Adressraums ein Kinderspiel ist.

Allerdings bringt die größere Größe der Zeiger auch einen großen Nachteil mit sich: Ansonsten benötigen identische Programme mehr Speicher auf einem 64-Bit-Prozessor (diese größeren Zeiger müssen irgendwo gespeichert werden). Da Zeiger ein häufiger Bestandteil von Programmen sind, kann dieser Unterschied den Cache belasten, was wiederum dazu führt, dass das gesamte System langsamer läuft. Perspektivisch können wir also sehen, dass eine Änderung der Prozessorarchitektur auf 64-Bit tatsächlich das gesamte System verlangsamen würde. Dieser Faktor muss also durch weitere Optimierungen an anderen Stellen ausgeglichen werden.

ARM64

Der A7, der 64-Bit-Prozessor, der das neue iPhone 5s antreibt, ist nicht nur ein normaler ARM-Prozessor mit breiteren Registern. ARM64 enthält wesentliche Verbesserungen gegenüber der älteren 32-Bit-Version.

Apple A7-Prozessor.

Registratur

ARM64 enthält doppelt so viele Ganzzahlregister wie 32-Bit-ARM (achten Sie darauf, die Anzahl und Breite der Register nicht zu verwechseln – wir haben im Abschnitt „64-Bit“ über die Breite gesprochen. ARM64 hat also sowohl doppelt so breite Register als auch doppelt so viele Register). Der 32-Bit-ARM verfügt über 16 Ganzzahlregister: einen Programmzähler (PC – enthält die Nummer des aktuellen Befehls), einen Stapelzeiger (ein Zeiger auf eine laufende Funktion), ein Linkregister (ein Zeiger auf die Rückkehr nach dem Ende). der Funktion) und die restlichen 13 sind für die Anwendungsnutzung vorgesehen. Der ARM64 verfügt jedoch über 32 Ganzzahlregister, darunter ein Nullregister, ein Linkregister, einen Frame-Zeiger (ähnlich einem Stapelzeiger) und eines, das für die Zukunft reserviert ist. Damit stehen uns 28 Register für die Anwendungsnutzung zur Verfügung, mehr als das Doppelte des 32-Bit-ARM. Gleichzeitig verdoppelte der ARM64 die Anzahl der Gleitkommazahl-Register (FPU) von 16 auf 32 128-Bit-Register.

Aber warum ist die Anzahl der Register so wichtig? Der Speicher ist im Allgemeinen langsamer als die CPU-Berechnungen und das Lesen/Schreiben kann sehr lange dauern. Dadurch müsste der schnelle Prozessor ständig auf Speicher warten und wir stoßen an die natürliche Geschwindigkeitsgrenze des Systems. Prozessoren versuchen, dieses Handicap durch Pufferschichten zu verbergen, aber selbst der schnellste (L1) ist immer noch langsamer als die Berechnung des Prozessors. Register sind jedoch Speicherzellen direkt im Prozessor und ihr Lesen/Schreiben ist schnell genug, um den Prozessor nicht auszubremsen. Die Anzahl der Register bedeutet praktisch die Größe des schnellsten Speichers für Prozessorberechnungen, was sich stark auf die Geschwindigkeit des gesamten Systems auswirkt.

Gleichzeitig benötigt diese Geschwindigkeit eine gute Optimierungsunterstützung durch den Compiler, damit die Sprache diese Register nutzen kann und nicht alles im allgemeinen Anwendungsspeicher (dem langsamen Speicher) ablegen muss.

Befehlssatz

ARM64 bringt auch große Änderungen am Befehlssatz mit sich. Ein Befehlssatz ist ein Satz atomarer Operationen, die ein Prozessor ausführen kann (z. B. „ADD register1 register2“ addiert die Zahlen in zwei Registern). Aus diesen Anweisungen setzen sich die für die einzelnen Sprachen verfügbaren Funktionen zusammen. Komplexere Funktionen müssen mehr Anweisungen ausführen und können daher langsamer sein.

Neu in ARM64 sind Anweisungen zur AES-Verschlüsselung, SHA-1- und SHA-256-Hash-Funktionen. Anstelle einer komplexen Implementierung ruft nur die Sprache diese Anweisung auf – was die Berechnung solcher Funktionen erheblich beschleunigt und hoffentlich die Sicherheit in Anwendungen erhöht. Z.B. Die neue Touch ID verwendet diese Anweisungen auch bei der Verschlüsselung und ermöglicht so echte Geschwindigkeit und Sicherheit (theoretisch müsste ein Angreifer den Prozessor selbst modifizieren, um auf die Daten zuzugreifen – was angesichts seiner geringen Größe gelinde gesagt unpraktisch ist).

Kompatibilität mit 32bit

Es ist wichtig zu erwähnen, dass der A7 vollständig im 32-Bit-Modus laufen kann, ohne dass eine Emulation erforderlich ist. Dies bedeutet, dass das neue iPhone 5s auf 32-Bit-ARM kompilierte Anwendungen ohne Verlangsamung ausführen kann. Allerdings kann er dann die neuen ARM64-Funktionen nicht nutzen, sodass es sich immer lohnt, einen speziellen Build nur für den A7 zu erstellen, der deutlich schneller laufen soll.

Laufzeitänderungen

Laufzeit ist der Code, der der Programmiersprache Funktionen hinzufügt, die er während der Ausführung der Anwendung bis nach der Übersetzung verwenden kann. Da Apple die Anwendungskompatibilität nicht aufrechterhalten muss (dass eine 64-Bit-Binärdatei auf 32-Bit läuft), könnten sie es sich leisten, noch ein paar Verbesserungen an der Objective-C-Sprache vorzunehmen.

Einer von ihnen ist der sogenannte markierter Zeiger (markierter Zeiger). Normalerweise werden Objekte und Zeiger auf diese Objekte in separaten Teilen des Speichers gespeichert. Neue Zeigertypen ermöglichen es jedoch Klassen mit wenigen Daten, Objekte direkt im Zeiger zu speichern. Durch diesen Schritt entfällt die Notwendigkeit, dem Objekt direkt Speicher zuzuweisen. Erstellen Sie einfach einen Zeiger und das darin enthaltene Objekt. Markierte Zeiger werden nur in der 64-Bit-Architektur unterstützt, auch weil in einem 32-Bit-Zeiger nicht mehr genügend Platz vorhanden ist, um genügend nützliche Daten zu speichern. Daher unterstützte iOS im Gegensatz zu OS X diese Funktion noch nicht. Mit der Einführung von ARM64 ändert sich dies jedoch, und auch in dieser Hinsicht hat iOS zu OS X aufgeschlossen.

Obwohl Zeiger 64 Bit lang sind, werden beim ARM64 nur 33 Bit für die eigene Adresse des Zeigers verwendet. Und wenn es uns gelingt, die restlichen Zeigerbits zuverlässig zu entlarven, können wir diesen Platz zum Speichern zusätzlicher Daten nutzen – wie im Fall der erwähnten getaggten Zeiger. Konzeptionell ist dies eine der größten Änderungen in der Geschichte von Objective-C, obwohl es sich nicht um eine marktfähige Funktion handelt – daher werden die meisten Benutzer nicht wissen, wie Apple Objective-C voranbringt.

Was die nützlichen Daten betrifft, die im verbleibenden Speicherplatz eines solchen markierten Zeigers gespeichert werden können, verwendet Objective-C diese jetzt beispielsweise zum Speichern der sogenannten Referenzanzahl (Anzahl der Referenzen). Bisher wurde der Referenzzähler an einer anderen Stelle im Speicher in einer dafür vorbereiteten Hash-Tabelle gespeichert, was jedoch bei einer großen Anzahl von Alloc-/Dealloc-/Retain-/Release-Aufrufen das gesamte System verlangsamen konnte. Die Tabelle musste aus Thread-Sicherheitsgründen gesperrt werden, sodass der Referenzzähler von zwei Objekten in zwei Threads nicht gleichzeitig geändert werden konnte. Dieser Wert wird jedoch neu in den Rest des sogenannten eingefügt isa Indikatoren. Dies ist ein weiterer unauffälliger, aber großer Vorteil und eine Beschleunigung in der Zukunft. Dies könnte jedoch in einer 32-Bit-Architektur nie erreicht werden.

Informationen über zugehörige Objekte, ob das Objekt schwach referenziert ist, ob es notwendig ist, einen Destruktor für das Objekt zu generieren usw., werden ebenfalls neu an die verbleibende Stelle der Zeiger auf die Objekte eingefügt. Dank dieser Informationen kann das Objective-C runtime ist in der Lage, die Laufzeit grundsätzlich zu beschleunigen, was sich in der Geschwindigkeit jeder Anwendung widerspiegelt. Laut Tests bedeutet dies eine Beschleunigung aller Speicherverwaltungsaufrufe um etwa 40–50 %. Einfach durch den Wechsel zu 64-Bit-Zeigern und die Nutzung dieses neuen Speicherplatzes.

Záver

Obwohl Konkurrenten versuchen werden, die Idee zu verbreiten, dass der Wechsel zu einer 64-Bit-Architektur unnötig sei, wissen Sie bereits, dass dies nur eine sehr uninformierte Meinung ist. Es stimmt, dass die Umstellung auf 64-Bit ohne Anpassung Ihrer Sprache oder Anwendungen nicht wirklich etwas bringt – es verlangsamt sogar das gesamte System. Aber der neue A7 verwendet ein modernes ARM64 mit einem neuen Befehlssatz, und Apple hat sich die Mühe gemacht, die gesamte Objective-C-Sprache zu modernisieren und die neuen Fähigkeiten zu nutzen – daher die versprochene Beschleunigung.

Hier haben wir zahlreiche Gründe genannt, warum eine 64-Bit-Architektur der richtige Schritt nach vorne ist. Es ist eine weitere Revolution „unter der Haube“, dank der Apple versuchen wird, nicht nur mit Design, Benutzeroberfläche und reichhaltigem Ökosystem, sondern vor allem mit den modernsten Technologien auf dem Markt an der Spitze zu bleiben.

Source: mikeash.com
.