Theoretische Mindestanzahl von Registern für einen modernen Computer?


10

Ich habe in meinem Grundstudium einen Kurs über Compiler besucht, in dem wir einen Compiler geschrieben haben, der Quellprogramme in einer Spielzeug-Java-ähnlichen Sprache zu einer Spielzeug-Assemblersprache kompiliert (für die wir einen Dolmetscher hatten). Im Projekt haben wir einige Annahmen über den Zielcomputer getroffen, die eng mit "echten" nativen ausführbaren Dateien zusammenhängen, darunter:

  • ein Laufzeitstapel, der von einem dedizierten Stapelzeigerregister ("SP") verfolgt wird
  • Ein Heap für die dynamische Objektzuweisung, der von einem dedizierten Heap-Zeigerregister ("HP") verfolgt wird
  • ein dediziertes Programmzählerregister ("PC")
  • Der Zielcomputer verfügt über 16 Register
  • Operationen an Daten (im Gegensatz zu z. B. Sprüngen) sind Register-zu-Register-Operationen

Als wir zur Einheit kamen, um die Registerzuordnung als Optimierung zu verwenden, fragte ich mich: Was ist die theoretische Mindestanzahl von Registern für eine solche Maschine? Sie können an unseren Annahmen erkennen, dass wir in unserem Compiler fünf Register (SP, HP, PC plus zwei zur Verwendung als Speicher für binäre Operationen) verwendet haben. Während Optimierungen wie die Registerzuweisung sicherlich mehr Register verwenden können, gibt es eine Möglichkeit, mit weniger auszukommen, während Strukturen wie der Stapel und der Heap beibehalten werden? Ich nehme an, dass wir bei der Registeradressierung (Register-zu-Register-Operationen) mindestens zwei Register benötigen, aber brauchen wir mehr als zwei?


Ein "Heap-Zeiger" scheint eine seltsame Idee zu sein. Denn im Gegensatz zum Stack ist der Heap kein LIFO und reduziert sich nicht auf Push / Pop-Semantik. Sie sollten die dynamische Speicherzuweisung eher als Aufruf von malloc / freien Routinen sehen.
Yves Daoust

Antworten:


14

Wenn Sie den direkten Speicherzugriff über die Speicheradresse zulassen, benötigen Sie keine "Register", da Sie stattdessen Speicherorte verwenden können. Zum Beispiel kann der Speicher an Position 0 der Programmzähler sein, an Position 1 haben wir den Stapelzeiger usw. Aber das ist Betrug.

Um zu verhindern, dass wir betrügen, nehmen wir an, dass es keinen direkten Speicherzugriff gibt, da wir feste Speicherorte als Register verwenden könnten. Dann können wir mit zwei Registern davonkommen, einem Programmzähler und einem Stapelzeiger, wie im Wikipedia-Artikel über Stapelmaschinen erläutert . Auf den Stapel kann nur über den Stapelzeiger zugegriffen werden, und auf das Programm kann nur über den Programmzähler zugegriffen werden.

Eine andere Möglichkeit ist die Verwendung von Gegenmaschinen. Eine Maschine mit zwei Zählern ist Turing vollständig, dh sie kann alles berechnen, was Turing kann. Dies wiederum ist in dem Wikipedia - Artikel über schön erklärt Zähler Maschinen .


Danke für Ihre Antwort! Der Artikel über Stapelmaschinen erwähnt jedoch, dass die Maschine direkten Speicherzugriff ermöglicht (um Operationen an den obersten Stapelelementen auszuführen und das Ergebnis wieder aufzuschieben), so dass immer noch betrogen wird, oder? Was die Thekenmaschine betrifft, habe ich diesen Artikel gelesen. Ich habe auch einen ähnlichen TC-Beweis eines 2-CM gelesen, aber beide beinhalten effektiv das Speichern des gesamten RAM in zwei Registern, was mir noch mehr wie Betrug erscheint.
BlueBomber

Nun, irgendwann betrügt es nicht mehr. Die Stapeloperationen betrügen nicht, solange sie keinen direkten Zugriff auf einen festen Speicherort im Speicher zulassen. Es ist in Ordnung, beispielsweise die drei obersten Elemente des Stapels drehen zu können. Ihre Frage ist sowieso ein bisschen seltsam, also lohnt es sich nicht, darüber nachzudenken, was betrügt und was nicht.
Andrej Bauer

Nochmals vielen Dank für die Antwort. Immer wenn sich das Thema auf theoretische Grenzen bezieht, ist Betrug noch weniger akzeptabel! Das heißt aber nicht, dass es nicht lehrreich ist. Der Punkt, an dem es nicht schummelt, ist, wenn es wohl nicht schummelt. Ich fand Ihre erste Antwort informativ, aber das Problem ist, dass unser Modell alle Modelle von Turing Machine, Counter Machine und Stack Machine überlappt und unter Berücksichtigung unserer Annahmen (einschließlich endlich vieler endlicher Register und ohne direkten Speicherzugriff) auskommen kann mit nur zwei Registern?
BlueBomber

1
Ich finde die Frage seltsam, weil es schwierig ist, reale Konzepte wie Prozessor, Register, Speicherzugriff usw. zu bestimmen, aber Sie müssen diese festhalten, um etwas beweisen zu können. Das Endergebnis wird also sein, dass alles, was Sie beweisen, leicht zu beweisen ist, aber es hängt sehr davon ab, wie Sie die Frage formalisieren (was Ihre theoretische Vorstellung von "Prozessor", "Register", "Speicher" usw. ist).
Andrej Bauer

1
Ein Compiler-Lehrbuch erlaubt es uns nicht, viel zu beweisen, zumindest nicht im mathematischen Sinne des Wortes "beweisen". Sie müssen bei der Formalisierung der Hardware noch einen Schritt weiter gehen, um zu etwas zu gelangen, das Beweise ermöglicht . Jedenfalls spalten wir uns die Haare und ich habe dir bereits meine beste Antwort gegeben.
Andrej Bauer

1

Die PIC-Architektur, die in den 1970er Jahren von General Instruments eingeführt wurde und heute noch verwendet wird, hatte die folgenden Register:

W register (not addressible)
01    Timer/Counter
02    Program Counter
03    Status
04    File-Select Register
05-07 One register for each I/O port
08-1F General-purpose registers/"memory"

Ein typischer Befehl liest ein Register, führt eine Berechnung mit dem Wert read und W durch und speichert das Ergebnis der Berechnung entweder in W oder in dem gelesenen Register. Eine der verfügbaren Berechnungen ergibt "den gelesenen Wert, wobei W ignoriert wird"; Ein anderes ist "nimm W, ignoriere den gelesenen Wert". Die Bitmuster, die "XX lesen, dann W nehmen, den gelesenen Wert ignorieren und das Ergebnis in W speichern" entsprechen würden, werden für NOP sowie eine Vielzahl von speziellen Anweisungen verwendet.

Um Adressberechnungen zu ermöglichen, sucht die Ausführungseinheit des Prozessors nach Anweisungen, die eine Adresse von 00 codieren, und ersetzt die Adresse durch den Inhalt des Dateiauswahlregisters.

Obwohl das Einspeisen aller Werte durch das W-Register ein Engpass sein kann, hat die PIC-Architektur einen größeren Arbeitssatz als andere Architekturen, die das Befehlswort gleicher Länge verwenden. Auf dem PIC16C54 (noch heute hergestellt und den PICs der 1970er Jahre sehr ähnlich) sind die Anweisungen 12 Bit lang. Bei vielen anderen 16Cxx- oder 16Fxx-Teilen sind Befehle 14 Bit lang und können direkt auf einen 128-Byte-Adressraum zugreifen. Wenn der Arbeitssatz eines Programms gut zum Arbeitssatz des Befehlssatzes passt, würde eine Anweisung wie "total + = value", wobei "total" und "value" vom Typ sind unsigned char, kompiliert zu:

movf  value,w
addwf total,f

Auf so etwas wie dem ARM wäre der Code eher so, selbst wenn ein Register mit der Basisadresse seiner Variablen vorinstalliert ist:

ldr    r0,[r7+value]
ldr    r1,[r7+total]
add    r1,r1,r0
str    r1,[r7+total]

In vielen Fällen kann ein Compiler das Laden und Speichern bei jeder Operation vermeiden, aber bei so etwas wie dem PIC können die Vorteile des größeren Arbeitssatzes manchmal die Einschränkungen überwiegen, die es mit sich bringt, ständig W durchlaufen zu müssen.

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.