Es gibt viele Gründe, warum Sie nicht nur eine große Anzahl von Registern haben:
- Sie sind eng mit den meisten Pipeline-Phasen verbunden. Für den Anfang müssen Sie ihre Lebensdauer verfolgen und die Ergebnisse an frühere Phasen zurückleiten. Die Komplexität wird sehr schnell unlösbar und die Anzahl der (buchstäblich) beteiligten Drähte wächst mit der gleichen Geschwindigkeit. Es ist flächenmäßig teuer, was letztendlich bedeutet, dass es nach einem bestimmten Punkt teuer in Bezug auf Leistung, Preis und Leistung ist.
- Es nimmt Platz für die Befehlskodierung ein. 16 Register belegen 4 Bit für Quelle und Ziel und weitere 4, wenn Sie 3-Operanden-Befehle (z. B. ARM) haben. Das ist eine Menge Befehlssatz-Codierungsraum, der nur zur Angabe des Registers benötigt wird. Dies wirkt sich schließlich auf die Decodierung, die Codegröße und erneut auf die Komplexität aus.
- Es gibt bessere Möglichkeiten, um das gleiche Ergebnis zu erzielen ...
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:
ldr r0, [r4]
add r0, r0, #1
str r0, [r4]
ldr r0, [r5]
add r0, r0, #1
str r0, [r5]
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.
ldr v0, [v2]
add v0, v0, #1
str v0, [v2]
ldr v1, [v3]
add v1, v1, #1
str v1, [v3]
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.