Warum haben wir nicht mehr Register in Mikroprozessoren?


18

Register sind theoretisch nicht erforderlich; Alle Mikroprozessoren würden weiterhin ohne Register arbeiten. Aber diese scheinbar triviale Ergänzung hat dazu beigetragen, Mikroprozessoren effizienter zu machen.

Warum können wir nicht mehr Register haben, um weiter davon zu profitieren? Sie sind nur Memory on Chip und man kann sich vorstellen, nicht sehr schwer hinzuzufügen? Welcher Faktor hat die Anzahl der Register so beeinflusst, wie sie jetzt sind und nicht, sagen wir 10x mehr?


8
@ Alper91 Viele Architekturen, hypothetisch und real, haben keine Register und es ist überhaupt nicht notwendig. Es ist einfach eine nützliche Optimierung.
Pipe

4
Hmm. Niemand hat den Sparc erwähnt. Die größte Implementierung könnte 520 Register enthalten (32 Fenster mal 16 Register, + 8 Globale). Ich erinnere mich sicher an sie.
Jonk

13
Ich denke, die Anzahl der Bits in der Anweisung, die Sie benötigen, um das Register anzugeben, ist ein großes Problem. Wenn Sie 1024 Register haben, benötigen Sie mindestens 30 Bits für jede arithmetische Anweisung - es sei denn, Sie fügen andere Einschränkungen hinzu, wie "Alle 3 Register müssen aus derselben Gruppe von 32 Registern stammen (in diesem Fall benötigen Sie 20 Bits).
user253751

8
@pipe - eigentlich erfordert so ziemlich jedes praktische Design "Register" im schematischen Sinne, denn selbst wenn Sie eine Stack-Maschine oder ähnliches bauen, müssen Sie einen Platz haben, um die Argumente für die ALU oder die Ausgaben zu speichern - Die meisten Speicher haben keine drei Zugangsports. Und eine Stapelmaschine braucht einen Stapelzeiger, der ... ein Register ist! Und lassen Sie uns Pipeline-Register nicht erwähnen. Sie können die Verwendung solcher "Register" vor dem Programmierer verbergen, aber Sie benötigen immer noch einige, und wahrscheinlich fast so viele wie eine primitive Registermaschine.
Chris Stratton

4
@ChrisStratton Sicher, aber solange sie nicht durch die ISA verfügbar gemacht werden, handelt es sich lediglich um ein Implementierungsdetail. Etwas sinnloses Argument, da wir nicht wissen, was OP unter Register zu verstehen ist .
Pipe

Antworten:


33

Es gibt mehrere Faktoren:

  • Hochleistungs-Mikroarchitekturen verwenden die Umbenennung von Registern. Das heißt, die Anzahl der physischen Register ist höher als die Anzahl der architektonisch sichtbaren Register und sie können deren unabhängige Verwendung verfolgen.

  • Verdoppelung der Anzahl der Register verdoppelt nicht die Leistung. ISTR (von Computer Architecture, A Quantitative Approach ), das von 16 auf 32 Register steigt, bringt unter der Annahme, dass der Anstieg keine nachteiligen Auswirkungen hat, eine Verbesserung um etwa 10% (was eine sehr optimistische Annahme ist).

  • Architektonisch sichtbare Register sind kostenpflichtig. Zum Beispiel:

    • Das Erhöhen ihrer Anzahl erhöht die Anzahl der Bits, die im Befehlsformat verwendet werden, um anzuzeigen, auf welches Register gerade zugegriffen wird (das Verdoppeln der Anzahl der Register impliziert, dass ein Bit mehr pro Register im Format vorhanden ist, wodurch verhindert wird, diese Bits für andere Verwendungen oder Forcen zu verwenden eine längere Anweisungsgröße).
    • Das Erhöhen der Anzahl der Architekturregister erhöht die Kosten für die Kontextumschaltung (da sie beim Kontextwechsel gespeichert und wiederhergestellt werden müssen).

1
Ich wette, dass die Leistungsverbesserung von 16 auf 32 Register völlig vom Optimierungspotential des fraglichen Compilers abhängt. In Assembler kann der Zugriff auf die doppelte Anzahl von Registern (in der x64-Architektur) die Leistung erheblich verbessern - allerdings nur für Nischenrollen und nur dann, wenn sie tatsächlich verwendet werden.
Rdtsc

6
@rdtsc: Der Wechsel von 8 zu 16 Architekturregistern führt zu einer deutlichen Verbesserung der Anzahl der Überläufe / Neuladungen für typischen Code. Dies geht aus den Daten der Simulationen hervor, die in einem mit dieser Antwort verknüpften Artikel enthalten sind . Dies wirkt sich auf die Codegröße, die Befehlsanzahl und die Bedeutung der Speicherweiterleitung mit niedriger Latenz aus. 16-> 32 ist ein viel kleinerer Effekt. AFAICT, 16 Architekturregister ist eine gute Wahl für Hardware mit Registerumbenennung, um WAR- und WAW-Gefahren zu beseitigen.
Peter Cordes

2
Intels AVX512 fügt jedoch 16 weitere Vektorregs hinzu, was insgesamt 32 ergibt. (Zusätzlich zur Verdoppelung der Breite auf 64 Byte, also einer vollen Cache-Zeile). Das Verbergen der Latenz vor Hochdurchsatz-Hochlatenz-FP-Operationen kann viele Register beanspruchen. Zum Beispiel hat Intel Haswell 5 c Lat, einen pro 0,5 c Durchsatz-FMA. Sie benötigen also 10 Vektorakkumulatoren, um die FMA-Ausführungseinheiten für eine Reduzierung zu sättigen (z. B. Skalarprodukt oder Summieren eines Arrays, bei dem die FMA Teil einer schleifengeführten Abhängigkeit ist ). x86-64 hat nur 16 Vektorregs. Aber denken Sie daran, Integer Ops, esp. Bei GP-Registern tritt selten eine Latenz von mehr als 1c auf.
Peter Cordes

1
Der Kompromiss ist für Ganzzahl-, FP- und Vektorregister unterschiedlich. Zum Beispiel ist ein verzögertes Speichern / Wiederherstellen von Integer-Registern nicht sinnvoll. Dies für Vektor 1 zu tun, ist eine weitaus bessere Wahl. Und Vektor-ISA haben oft mehr Register als Ganzzahl eins (AltiVec hat mindestens bis zu 128, ISTR hat ungefähr eine 256 für Sparc gelesen, kann aber jetzt keine Referenz finden).
AProgrammer

1
en.wikipedia.org/wiki/AltiVec hat zweiunddreißig 128b Vektorregs. Ich wurde neugierig auf SPARC und sah nach, wie das Registerfenster für Kontextwechsel funktioniert. Es sind 32 Register gleichzeitig sichtbar, es wird jedoch ein Schiebefenster für eine größere Registerdatei verwendet. In dieser vereinfachten Version muss das Betriebssystem die Größe der gesamten Schiebefenster-Registerdatei kennen, um sie zu speichern / wiederherzustellen, denn obwohl die Anweisungen für die Fensterführung Speicher zum Speichern / Wiederherstellen von Registern bereitstellen, erfolgt dies durch Überfüllen zum OS.
Peter Cordes

16

Während Register und RAM beide Speicher sind, wird auf unterschiedliche Weise auf sie zugegriffen, um die Kosten (im Chipbereich oder von verborgenen Taktzyklen) des Zugriffs auf sie widerzuspiegeln.

Register sind eng an die ALU gebunden und können viele Funktionen von Datenquellen, Senken, Modifizierern usw. übernehmen. Sie benötigen daher eine Fülle von breiten Multiplexverbindungen. In einigen Architekturen können wir R1 <= R2 + R3 schreiben, und genau das passiert in einem einzigen Taktzyklus. Jedes Register wird direkt im Operationscode adressiert, diese Adressierung ist eine sehr begrenzte Ressource.

Da die Implementierung von Registern teuer ist, ist die Anzahl in den meisten Architekturen normalerweise auf die Größenordnung von 10/20 beschränkt.

Der Arbeitsspeicher ist lose an die CPU gebunden und wird normalerweise über eine einzige gemeinsam genutzte Verbindung geleitet. Dies macht es sehr viel billiger, eine große Menge an RAM zu implementieren. RAM-Adressen stammen im Allgemeinen von einer in einem Register gespeicherten Adresse, verbrauchen also keine signifikante Befehlsbreite.

SPARC ist eine interessante Architektur mit 72 bis 640 64-Bit-Registern und einem 32-Register-Kontext, der mit Überlappungen für schnelle Unterprogrammaufrufe mit Parameterübergabe verschoben werden kann. Sie finden sie normalerweise nicht auf PCs und Servern, auf denen die Kosten eine Rolle spielen, wie in 99,999% der Anwendungen.


4
Ein weiterer Aspekt ist das Speichern / Wiederherstellen von Registern während eines Kontextwechsels. Mehr Register, mehr Zeit.
Michel Billaud

Ich würde bemerken, dass der alte TMS9900 alle seine Arbeitsregister im externen Speicher hielt. En.wikipedia.org/wiki/Texas_Instruments_TMS9900
Peter Smith

1
Ich hatte mich ausnahmslos mit qualifiziert (mit Ausnahme einiger Optimierungen), nahm es aber heraus, um es zu vereinfachen. Vielleicht ändere ich es einfach auf "allgemein". Wenn Sie die Ausnahmen finden und verstehen können, muss ich Sie nicht darauf hinweisen. Wenn Sie nicht in die Irre geführt werden können, spielt das keine Rolle, da Sie sonst keine Probleme bekommen. TMS9900, das war komisch, ich hatte 99/4 für meine Sünden in einem früheren Leben, seltsames Biest!
Neil_UK

Itanium hat auch Registerfenster.
Simon Richter

1
@ChrisStratton: Während es einige Präzedenzfälle gibt, in denen "Sie können die Register X und Y nicht verwenden" als Teil eines "ABI" betrachtet werden (z. B. k0- und k1-Register in MIPS), ist dies eine ungewöhnliche Verwendung. Sicher gibt es unerwünschte / unsichere verdeckte Nachrichtenübermittlungskanäle zwischen Prozessen, wenn das Speichern / Wiederherstellen dieser "ABI-verbotenen Register" beim Kontextwechsel nicht durchgeführt wird. Das heißt, Prozesse, die nicht kommunizieren können sollten, können dies möglicherweise tun, indem sie Informationen in den verbotenen Registern speichern und auf Kontextwechsel warten.
R ..

12

Register müssen innerhalb der Instruktion adressiert werden. Wenn es viele Register gibt, ist der Befehl länger. Das Speichern und Wiederherstellen von Registerinhalten für einen Interrupt-Dienst benötigt mehr Zeit, wenn viele Register vorhanden sind.


5

Wie die meisten Dinge ist die Anzahl der Register ein Kompromiss zwischen Kosten, Komplexität und Nützlichkeit.

Register werden als statisches RAM mit mehreren Ports implementiert, wodurch sie teurer (Chipfläche) sind als andere Speicheroptionen.

Dann werden sie mit dem Befehlssatz des Prozessors gekoppelt, wobei ein Erhöhen der Anzahl von Registern die Komplexität des Befehlssatzes erhöht. Wenn Sie also mit dem Befehlssatz kompatibel bleiben möchten, können Sie nicht einfach die Anzahl der in der nächsten Prozessorgeneration verfügbaren Register erhöhen, um die Effizienz zu erhöhen, da die Programme diese nicht verwenden würden.

Wie viele Register benötigen Sie wirklich? Ihre Nützlichkeit ist begrenzt. Stellen Sie sich vor, Sie schreiben einen Algorithmus, der eine mathematische Operation mit 1024 Bytes ausführt. Nehmen wir an, Sie multiplizieren mit 5. Bei der aktuellen Registeranzahl erhalten Sie Folgendes:

load operand1=5
load address
loop: load operand2=byte1@address
multiply Register1 with Register2
store result
increment address
if address = end goto endLoop
jump loop
endLoop:

Wenn Sie nun 1024 Register und alle darin gespeicherten Daten hätten, würde Ihr Programm folgendermaßen aussehen:

multiply Register1 with Register2
multiply Register1 with Register3
multiply Register1 with Register4
multiply Register1 with Register5
multiply Register1 with Register6
...

Da jeder von ihnen eine andere Anweisung ist, muss jeder einzelne von ihnen ausgeschrieben werden. Ihr benötigter Programmspeicher explodiert also. Nachdem Sie dies erkannt haben, möchten Sie vielleicht einige Anweisungen einführen, wie z multiply register1 with register(2 to 256). Aber wann würden Sie aufhören, geben Sie eine Anleitung für alle Kombinationen?

Vielleicht ist die Anzahl, über die wir derzeit verfügen, ein guter Kompromiss zwischen Kosten, Komplexität und Nützlichkeit.


1
Ich denke das Programm multiply Register1 with Register2 multiply Register1 with Register3 für sehr unrealistisch, da die Daten direkt oder indirekt von außerhalb des Computers stammen müssen, die Register also geladen werden müssen und die Ergebnisse direkt oder indirekt irgendwo verwendet werden müssen, damit die Register gespeichert werden müssen. In der Realität wird ein anständiger Optimierungs-Compiler für eine Hochsprache die Schleife des ersten Programms "ausrollen", um so etwas wie das zweite Programm zu erstellen, wobei die Registernutzung, die Speicherlatenz, möglicherweise die Cache-Belegung und die Ausführungsgeschwindigkeit optimiert werden.
gbulmer

1
Viele spezielle multiply register1 with register(2 to 256)Anweisungen sind nicht erforderlich . Das Pipelining verbessert den CPU-Durchsatz erheblich, insbesondere, um Anweisungen einfacher dekodieren und ausführen zu können. Der Effekt komplexer, massiver Varieté-Befehle kann also durch Verwendung mehrerer einfacher Befehle mit einer höheren Ausführungsrate erzielt werden. Eine größere Anzahl von Registern hilft, indem der Compiler viele unabhängige Anweisungen (solche, die kein Register gemeinsam haben) generieren kann, die unabhängig voneinander ausgeführt werden können, wodurch der Durchsatz verbessert wird. Ihr Beispiel = mehr Register sind besser.
gbulmer

4

Register sind sehr teuer. Sehr teuer. Es sind nicht so sehr die Register selbst, sondern alle Verbindungen von und zu den Registern. Angenommen, Sie haben eine Anweisung reg1 = reg2 + reg3. Um dies schnell zu implementieren , müssen Sie in einem Zyklus Daten aus zwei Registern lesen und im zweiten Zyklus in ein anderes Register schreiben. Wenn Sie nun einen Prozessor haben, der mehrere Befehle pro Zyklus ausführen kann, beispielsweise drei Befehle, müssen Sie in der Lage sein, Daten aus sechs Registern pro Zyklus zu lesen und Daten in drei Register zu schreiben. Das ist eine schreckliche Menge sehr schneller Verbindungen.

Natürlich können Sie auch einfach mehr Transistoren verwenden. Das Problem ist: Die Geschwindigkeit sinkt. Sie benötigen mehr Hardware, um aus mehr Registern auswählen zu können. Der Platz für die Registerdatei wird größer. All das macht die Dinge langsamer. Mit der gleichen Technologie sind Sie möglicherweise in der Lage, 16 Register mit 2.600 MHz oder 32 Register mit 2.400 MHz zu betreiben. Jetzt müssen die zusätzlichen Register einen signifikanten Abfall der Taktrate ausgleichen.


2

Welcher Faktor hat die Anzahl der Register beeinflusst?

- Speicherhierarchie

Register, Cache und RAM sind alle mit unterschiedlichen Speichertechnologien implementiert.

Unterschiedliche Technologien unterscheiden sich in

  1. Zugriffszeiten
  2. Kosten
  3. Dichte

Ein Beispiel: Die internen Register in einer CPU sind statische Arbeitsspeicher , während der Hauptspeicher des Computers dynamischer Direktzugriffsspeicher ist

Eine statische RAM-Binärzelle wird unter Verwendung einer 6-Transistor-Schaltung implementiert, während eine dynamische RAM-Binärzelle unter Verwendung eines Kondensators und eines Transistors implementiert wird. Vergleich von SRAM und DRAM

  • SRAM-Speicher ist viel schneller als DRAM-Speicher [wenige Zyklen für den Zugriff auf SRAM im Vergleich zu DRAM]
  • Die SRAM-Schaltung verbraucht weniger Energie als der DRAM
  • DRAM erfordern im Gegensatz zu SRAM ein periodisches Auffrischen jedes Bits im Speicher
  • SRAM kostet mehr als DRAM
  • SRAM hat im Vergleich zum DRAM eine geringere Dichte

Daher ist es nicht praktikabel, die Anzahl der schnellen, teuren Speicher mit geringerer Speicherdichte zu erhöhen. In der Tat könnten wir einige von ihnen verwenden, und ein gut geschriebenes Programm speichert die am häufigsten verwendeten Daten in diesen schnellen Registern, während die weniger häufig verwendeten Daten im langsameren Speicher gespeichert werden.

- Anweisungslänge

Die Adresse der Register ist in einem Befehl enthalten, der die Anzahl der zugreifbaren Register basierend auf der Anzahl der Bits begrenzt, die die Adresse darstellen können. Beispielsweise enthält in der MIPS-Architektur der 32-Bit-Längenbefehl nur 5 Bits, um die Adresse der zugreifbaren Register darzustellen, wodurch die Anzahl der Register auf 2 5 = 32 Register begrenzt wird. Das Erhöhen der Anzahl der Register würde das Erhöhen der Befehlslänge erfordern, um genügend Bits einzuschließen, die auf alle Register zugreifen könnten.


2

Wenn Sie sich den Befehlssatz eines Prozessors ansehen, gibt es verschiedene Möglichkeiten, diese zu gruppieren. Beispielsweise können alle ADDAnweisungen und alle XORAnweisungen zu einer Gruppe zusammengefasst werden .

Innerhalb jeder Gruppe desselben Befehls kann es Versionen geben, die im Speicher oder in Registern arbeiten. Diese Untergruppierung definiert effektiv die Anzahl der Register, über die der Prozessor verfügt.

Nehmen wir als hypothetisches 8-Bit-Beispiel an, dass die $AxAnweisungen die ADDAnweisungen und $Cxmöglicherweise die XORAnweisungen sind. Bei diesem Entwurf sind nur noch vier Bits zum Definieren der Operanden verfügbar!

  • Man kann nur vier Allzweckregister haben und zwei Bits verwenden, um eines zu definieren, und zwei Bits, um das andere zu definieren.
  • Oder man kann das erste Bit verwenden, um "spezielle" Varianten zu unterscheiden, und die anderen 3 Bits, um zu definieren, welche der acht Register mit dem Akkumulator arbeiten sollen ( $x0könnte der Akkumulator selbst sein).
  • Oder man könnte mehr als diese Anzahl von Registern haben - aber dann begrenzen, welche Register für welche Befehle zugänglich sind.

Natürlich sind wir hinter 8-Bit-Befehlssätzen. Diese Logik hat jedoch in der Vergangenheit bei der Definition von Registersätzen geholfen - und wird dies auch in Zukunft tun.

EDIT (wie gewünscht)

Sagen Sie den oberen vier Bits für den Befehl sind: ADD, SUB, XOR, MOV, CMPetc. Es gibt 16 Möglichkeiten. Dann wird für diese Befehle in dem Register-zu-Register ist sinnvoll (zB ADD Rx,Ry), müssen Sie angeben , Rxund Ry. Sagen wir, die nächsten beiden Bits sind für xund die letzten beiden sind für y. Somit:

ADD R1, R2  =>  'ADD' + 'R1' + 'R2' => $A0 + $04 + $02

Mit nur zwei Bits, um ein solches Register zu definieren, haben Sie nur Platz für insgesamt vier Register!

Im Übrigen werden Sie feststellen, dass einige Registerkombinationen keinen Sinn ergeben. Zum Beispiel MOV Rx, Rx(macht nichts) und SUB Rx, Rx(produziert immer 0). Dies können spezielle Anweisungen sein:

  1. SUB Rx, Rxwerden könnte NOT Rx- eine Einzeloperandenanweisung.
  2. MOV Rx, Rxkönnte zu einer MOVAnweisung werden, die ein zweites Byte als unmittelbaren Wert annimmt und als interpretiert wird MOV Rx, #$yy.

Auf diese Weise können Sie mit der Anweisungsübersicht "spielen" und die Löcher für ansonsten nutzlose oder unsinnige Anweisungen ausfüllen, um einen größeren Anweisungssatz für den Programmierer bereitzustellen. Letztendlich definiert der Befehlssatz den Registersatz.


Ich bin immer noch verwirrt, können Sie erklären, wie nur noch 4 Bit für Operanden übrig sind?
Darshan Chaudhary

Überprüfen Sie meine aktualisierte Antwort
John Burger

1
IMHO würde diese Antwort durch Verschieben des " hypothetischen Beispiels, das von einem 8-Bit-Befehlssatz ausgeht " an den Anfang der Frage erheblich verbessert . Ich habe Zeit damit verschwendet, einen Sinn daraus zu machen, bin zu dem Schluss gekommen, dass es nur für einen 8-Bit-Befehl mit fester Länge Sinn macht, und dann weitergelesen, um herauszufinden, ob dies der Fall ist. IMHO ist diese Art von Befehlssatz im Kontext der Frage nicht sehr irrelevant; sein gesamter Adressraum könnte eng mit dem statischen RAM gekoppelt sein. Ich denke auch, dass der Teil, der mit " Einige Registerkombinationen machen keinen Sinn ... " beginnt, für die Frage nicht relevant ist und gelöscht werden könnte. Mein $ 0.02
gbulmer

-2

Intel verwendet heutzutage Tausende von Registern - Hunderte pro CPU-Kern. Die größte Datenmenge, die auf einer CPU gespeichert ist, befindet sich jedoch im Cache, wodurch die Frage indirekt beantwortet wird. Der Cache ist in Schichten organisiert, mit einem kleinen schnellen L1-Cache und langsameren L2- und L3-Caches in größerer Entfernung. Die Registerdatei ist in gewissem Sinne L0, noch schneller als L1, aber auch noch kleiner. Sie könnten also die Anzahl der Register erhöhen, dies würde sie jedoch wahrscheinlich verlangsamen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.