In 32bit hatten wir 8 "Allzweck" -Register. Mit 64-Bit verdoppelt sich die Menge, aber es scheint unabhängig von der 64-Bit-Änderung selbst zu sein.
Wenn die Register so schnell sind (kein Speicherzugriff), warum gibt es dann natürlich nicht mehr davon? Sollten CPU-Builder nicht so viele Register wie möglich in die CPU einbauen? Was ist die logische Einschränkung, warum wir nur den Betrag haben, den wir haben?
88
Antworten:
Es gibt viele Gründe, warum Sie nicht nur eine große Anzahl von Registern haben:
Heutzutage haben wir wirklich viele Register - sie sind einfach nicht explizit programmiert. Wir haben "Register Umbenennung". Während Sie nur auf einen kleinen Satz (8-32 Register) zugreifen, werden diese tatsächlich von einem viel größeren Satz (z. B. 64-256) unterstützt. Die CPU verfolgt dann die Sichtbarkeit jedes Registers und ordnet sie dem umbenannten Satz zu. Sie können beispielsweise mehrere Male hintereinander laden, ändern und dann in einem Register speichern und jede dieser Operationen unabhängig von Cache-Fehlern usw. unabhängig ausführen lassen. In ARM:
Cortex A9-Kerne registrieren das Umbenennen von Registern, sodass das erste Laden von "r0" tatsächlich in ein umbenanntes virtuelles Register erfolgt - nennen wir es "v0". Das Laden, Inkrementieren und Speichern erfolgt auf "v0". In der Zwischenzeit führen wir auch wieder ein Laden / Ändern / Speichern von r0 durch, das jedoch in "v1" umbenannt wird, da dies eine völlig unabhängige Sequenz ist, die r0 verwendet. Angenommen, die Last vom Zeiger in "r4" ist aufgrund eines Cache-Fehlers ins Stocken geraten. Das ist in Ordnung - wir müssen nicht warten, bis "r0" fertig ist. Da es umbenannt wurde, können wir die nächste Sequenz mit "v1" (ebenfalls auf r0 abgebildet) ausführen - und vielleicht ist das ein Cache-Hit und wir hatten gerade einen riesigen Leistungsgewinn.
Ich denke, x86 hat heutzutage eine gigantische Anzahl umbenannter Register (Baseballstadion 256). Das würde bedeuten, 8 Bit mal 2 für jeden Befehl zu haben, nur um zu sagen, was die Quelle und das Ziel sind. Dies würde die Anzahl der im Kern benötigten Drähte und seine Größe massiv erhöhen. Es gibt also einen Sweet Spot zwischen 16 und 32 Registern, mit dem sich die meisten Designer zufrieden gegeben haben, und bei CPU-Designs außerhalb der Reihenfolge ist das Umbenennen von Registern der Weg, dies zu verringern.
Bearbeiten : Die Bedeutung der Ausführung außerhalb der Reihenfolge und der Umbenennung von Registern. Sobald Sie OOO haben, spielt die Anzahl der Register keine Rolle mehr, da es sich nur um "temporäre Tags" handelt, die in den viel größeren virtuellen Registersatz umbenannt werden. Sie möchten nicht, dass die Zahl zu klein ist, da es schwierig wird, kleine Codesequenzen zu schreiben. Dies ist ein Problem für x86-32, da die begrenzten 8 Register bedeuten, dass viele temporäre Elemente den Stapel durchlaufen und der Kern zusätzliche Logik benötigt, um Lese- / Schreibvorgänge in den Speicher weiterzuleiten. Wenn Sie kein OOO haben, sprechen Sie normalerweise von einem kleinen Kern. In diesem Fall ist ein großer Registersatz ein schlechter Kosten- / Leistungsvorteil.
Es gibt also einen natürlichen Sweet Spot für die Größe der Registerbank, der für die meisten CPU-Klassen maximal 32 Architekturregister umfasst. x86-32 hat 8 Register und ist definitiv zu klein. ARM hat 16 Register und es ist ein guter Kompromiss. 32 Register sind etwas zu viele, wenn überhaupt - Sie brauchen am Ende nicht die letzten 10 oder so.
Nichts davon berührt die zusätzlichen Register, die Sie für SSE und andere Vektor-Gleitkomma-Coprozessoren erhalten. Diese sind als zusätzlicher Satz sinnvoll, da sie unabhängig vom ganzzahligen Kern ausgeführt werden und die Komplexität der CPU nicht exponentiell erhöhen.
quelle
Wir tun haben mehr von ihnen
Da fast jeder Befehl 1, 2 oder 3 architektonisch sichtbare Register auswählen muss, würde eine Erweiterung ihrer Anzahl die Codegröße bei jedem Befehl um mehrere Bits erhöhen und so die Codedichte verringern. Es erhöht auch die Menge an Kontext , die als Thread-Status gespeichert und teilweise im Aktivierungsdatensatz einer Funktion gespeichert werden muss . Diese Operationen treten häufig auf. Pipeline-Verriegelungen müssen für jedes Register eine Anzeigetafel überprüfen, und dies hat eine quadratische zeitliche und räumliche Komplexität. Und vielleicht ist der größte Grund einfach die Kompatibilität mit dem bereits definierten Befehlssatz.
Aber es stellt sich heraus, dank Umbenennung registrieren , wir wirklich haben viele Register zur Verfügung, und wir brauchen noch nicht einmal , sie zu retten. Die CPU verfügt tatsächlich über viele Registersätze und wechselt automatisch zwischen diesen, wenn Ihr Code ausgeführt wird. Dies geschieht lediglich, um mehr Register zu erhalten.
Beispiel:
In einer Architektur mit nur r0-r7 kann der folgende Code von der CPU automatisch wie folgt umgeschrieben werden:
In diesem Fall ist r10 ein verstecktes Register, das r1 vorübergehend ersetzt. Die CPU kann erkennen, dass der Wert von r1 nach dem ersten Speichern nie wieder verwendet wird. Dadurch kann das erste Laden verzögert werden (selbst ein On-Chip-Cache-Treffer dauert normalerweise mehrere Zyklen), ohne dass die Verzögerung des zweiten Ladens oder des zweiten Speichers erforderlich ist.
quelle
Sie fügen ständig Register hinzu, sind jedoch häufig an spezielle Anweisungen (z. B. SIMD, SSE2 usw.) gebunden oder müssen auf eine bestimmte CPU-Architektur kompiliert werden, was die Portabilität verringert. Bestehende Anweisungen arbeiten häufig mit bestimmten Registern und können andere Register nicht nutzen, wenn sie verfügbar sind. Legacy-Befehlssatz und alles.
quelle
Um hier ein paar interessante Informationen hinzuzufügen, werden Sie feststellen, dass Opcodes mit 8 Registern gleicher Größe die Konsistenz mit der hexadezimalen Notation aufrechterhalten können. Zum Beispiel ist der Befehl
push ax
auf x86 Opcode 0x50 und geht für das letzte Register di auf 0x57. Dannpop ax
beginnt der Befehl bei 0x58 und geht bis zu 0x5Fpop di
, um die erste Basis-16 zu vervollständigen. Die hexadezimale Konsistenz wird mit 8 Registern pro Größe beibehalten.quelle