Warum müssen Compiler für die RISC-Befehlssatzarchitektur „intelligenter“ sein?

Warum müssen Compiler für die RISC-Befehlssatzarchitektur „intelligenter“ sein?

Reduced Instruction Set Architecture (RISC) zielt darauf ab, die Anzahl der Befehle zu reduzieren und dadurch die Leistung zu verbessern. Der einzige Nachteil dieses Ansatzes besteht darin, dass die Compiler „intelligenter“ sein müssen.

Was meint meine Dozentin mit der Aussage „Compiler müssen intelligenter sein“ und warum ist das so?

Antwort1

RISC steht, wenn man es genau nimmt, für „Reduced Instruction Set Complexity“ (reduzierte Befehlssatzkomplexität). Dabei wird die Anzahl der Befehle nicht unbedingt reduziert, aber jeder Befehl wird einfacher, sowohl im Hinblick auf die zu seiner Ausführung erforderlichen Maschinenzyklen als auch im Hinblick auf die Anzahl der Gates (oder Mikrocode-Speicher), die seiner Implementierung gewidmet sind.

Die Theorie (die zumindest teilweise realisiert ist) besagt, dass durch die Reduzierung der Steuerlogik mehr Chipplatz für Register und Datenpfade zur Verfügung steht. Daher haben RISC-Maschinen normalerweise 2-4 Mal so viele Register wie ihre CISC-Gegenstücke.

Dies überlässt dem Compiler die Arbeit der ausgelassenen Steuerlogik, einschließlich der „Planung“ von Operationen (deren Sequenzierung), sodass Sie beispielsweise nicht zwei Additionen hintereinander durchführen, sondern eine Addition und dann eine Verschiebung (und zwar in unterschiedlichen Registern), sodass sowohl der Addierer als auch der Verschieber optimal genutzt werden. Und der Compiler muss auch den Registersatz verwalten, um die Bewegung in und aus Registern zu optimieren und Speicherzugriffe zu minimieren. Außerdem muss der Compiler wissen, wie er die ungeraden Anweisungen am besten nutzt (z. B. „eine nach links verschieben und mit Literal maskieren“), da diese normalerweise in einem (vielleicht seltsamen) Szenario relativ leistungsstark sind.

Infolgedessen sind die von einem guten RISC-Compiler generierten Anweisungen praktisch unmöglich zu entziffern. Selbst wenn Sie den Befehlssatz gut kennen, ist es bestenfalls schwierig herauszufinden, dass sich in Register 12 noch immer ein Wert von vor einer halben Stunde befindet, selbst wenn nicht ständig komplizierte Verschiebe- und Maskierungsvorgänge stattfinden würden.

(Für diejenigen, die anscheinend nicht glauben, dass ich weiß, wovon ich spreche: Ich war Anfang der 70er Jahre zum ersten Mal mit RISC beim IBM 801 beschäftigt und war mit George Radin und Marty Hopkins per Du.)

Antwort2

Da eine RISC-CPU weniger Anweisungen enthält, ist die Wahrscheinlichkeit geringer, dass sich eine einzelne Anweisung auf höherer Ebene problemlos in einen einzelnen Operationscode in Maschinensprache übersetzen lässt.

Ein Synonym für RISC-CPU ist „Load-Store-Architektur“. Im Grunde bedeutet dies, dass RISC-Anweisungen, die tatsächlich funktionieren, im Allgemeinen nur mit Registern arbeiten. Wenn Sie mit im RAM gespeicherten Werten arbeiten möchten, müssen Sie explizite LOAD-Anweisungen ausgeben, während CISC-CPUs wie x86 Anweisungen haben, die dies automatisch tun. RISC-CPUs hatten historisch gesehen mehr Register als x86 – und guter Code wird die verfügbaren Register gut verwalten, um unnötige Speicherzugriffe zu vermeiden, was bedeutet, dass ein Compiler dies berücksichtigen muss.

Ein weiterer Grund besteht darin, dass RISC-CPUs normalerweise nur die für die Verknüpfung erforderliche Mindestinfrastruktur bereitstellen.

Beispielsweise haben x86-CPUs das Konzept eines „Stapels“, in den Sie Werte schieben und später „herausziehen“ können (es gibt PUSHund POP-Anweisungen). Es gibt auch eine CALLAnweisung – sie schiebt den aktuellen Anweisungszeiger auf den Stapel und springt dann zur Zieladresse – normalerweise eine Subroutine oder Funktion. Eine RETAnweisung kann dann später ausgegeben werden, um den gespeicherten Anweisungszeiger herauszuziehen und die ursprüngliche Funktion fortzusetzen. Das Verschachteln von Subroutinen ist praktisch, und Sie können PUSHund verwenden POP, um Parameter für Subroutinen einfach festzulegen.

Auf einem MIPS beispielsweise gibt es nur ein jal"Jump and Link" - es legt den aktuellen Befehlszeiger in ein Register und springt dann zu dieser Adresse. Wenn Sie etwas wie einen Stack oder den x86- CALLBefehl ausführen möchten, müssen Sie das manuell tun. Dies erfordert mehr Intelligenz vom Compiler.

Antwort3

CISC-Prozessoren (Complex Instruction Set Computing) verfügen über eine größere Befehlspalette als RISC-Prozessoren (Reduced Instruction Set Computing).

Ein Beispiel für eine Multiplikation in CISC wäre: MUL 1:3, 4:2 (Multiplikation von 1:3 und 2:4). Dieser Befehl würde den Wert in Position 1:3 in sein Register laden, den Wert in 4:2 laden, beides miteinander multiplizieren und wieder in 1:3 speichern.

RISC-CPUs könnten Folgendes müssen:

  • LADE A, 1:3
  • LAST B, 4:2
  • PROD A, B
  • GESCHÄFT 1:3, A

...4 RISC-Operationen zu 1 CISC-Operation.

Denn selbst für die einfachste Multiplikationsberechnung sind bei RISC mehr Operationen erforderlich. Stellen Sie sich vor, wie viel mehr Arbeit beispielsweise für die Videowiedergabe oder beim Gaming erforderlich ist.

In diesem Sinne müssen die Compiler, die die Software aus dem vom Programmierer eingegebenen Code erstellen, „intelligenter“ sein, damit sie wissen, wie komplexe Codeteile und Befehle für die RISC-Architektur vereinfacht werden.

Ich hoffe, das ist verständlich. Für weitere Informationen lohnt sich möglicherweise ein Blick auf: http://www.engineersgarage.com/articles/risc-and-cisc-architecture?page=5

verwandte Informationen