webentwicklung-frage-antwort-db.com.de

Warum versteckt Intel den internen RISC-Kern in seinen Prozessoren?

Beginnend mit Pentium Pro (P6-Mikroarchitektur) hat Intel seine Mikroprozessoren neu gestaltet und den internen RISC-Kern gemäß den alten CISC-Anweisungen verwendet. Seit Pentium Pro sind alle CISC-Anweisungen in kleinere Teile (uops) unterteilt und werden dann vom RISC-Kern ausgeführt.

Am Anfang war mir klar, dass Intel beschlossen hat, neue interne Architekturen zu verbergen und Programmierer zu zwingen, "CISC Shell" zu verwenden. Dank dieser Entscheidung konnte Intel die Architektur der Mikroprozessoren vollständig umgestalten, ohne die Kompatibilität zu beeinträchtigen.

Ich verstehe jedoch nichts, warum Intel noch so viele Jahre lang einen internen RISC-Befehlssatz verbirgt. Warum ließen sie Programmierer keine RISC-Anweisungen wie die alten x86-CISC-Anweisungen verwenden?

Wenn Intel die Abwärtskompatibilität so lange beibehält (wir haben immer noch den virtuellen 8086-Modus neben dem 64-Bit-Modus), warum erlauben sie uns nicht, Programme zu kompilieren, damit sie die CISC-Anweisungen umgehen und den RISC-Core direkt verwenden? Dies eröffnet eine natürliche Möglichkeit, den heutzutage veralteten x86-Befehlssatz langsam aufzugeben (dies ist der Hauptgrund, warum sich Intel für die Verwendung des RISC-Kerns im Inneren entschieden hat, oder?).

Wenn ich mir die neue Intel Core i-Serie anschaue, sehe ich, dass sie nur den CISC-Befehlssatz um AVX, SSE4 und andere erweitert.

84
Goofy

Nein, der x86-Befehlssatz ist sicherlich nicht veraltet. Es ist so beliebt wie immer. Der Grund, warum Intel einen Satz von RISC-ähnlichen Mikrobefehlen intern verwendet, liegt darin, dass diese effizienter verarbeitet werden können.

Eine x86-CPU arbeitet also mit einem ziemlich leistungsstarken Decoder im Frontend, der x86-Anweisungen akzeptiert und sie in ein optimiertes internes Format konvertiert, das das Backend verarbeiten kann.

Um dieses Format "externen" Programmen zugänglich zu machen, gibt es zwei Punkte:

  • es ist kein stabiles Format. Intel kann zwischen CPU-Modellen wechseln, um sie an die jeweilige Architektur anzupassen. Dies ermöglicht es ihnen, die Effizienz zu maximieren, und dieser Vorteil würde verloren gehen, wenn sie sich auf ein festes, stabiles Anweisungsformat sowohl für den internen als auch für den externen Gebrauch festlegen müssten.
  • es gibt einfach nichts zu gewinnen, wenn man es tut. Bei den heutigen großen, komplexen CPUs ist der Decoder ein relativ kleiner Teil der CPU. Das Dekodieren von x86-Befehlen macht das komplexer, aber der Rest der CPU bleibt davon unberührt. Insgesamt kann also nur sehr wenig gewonnen werden, insbesondere, weil das x86-Frontend noch vorhanden sein muss, um "Legacy" -Code auszuführen . Sie würden also nicht einmal die Transistoren speichern, die derzeit im x86-Frontend verwendet werden.

Dies ist keine perfekte Anordnung, aber die Kosten sind relativ gering und es ist eine viel bessere Wahl, als die CPU so zu gestalten, dass sie zwei völlig unterschiedliche Befehlssätze unterstützt. (In diesem Fall würden sie wahrscheinlich einen dritten Satz von Mikro-Ops für den internen Gebrauch erfinden, nur weil diese frei angepasst werden können, um die interne Architektur der CPU am besten zu erfüllen.)

85
jalf

Die wahre Antwort ist einfach.

Der Hauptgrund für die Implementierung von RISC-Prozessoren war die Reduzierung der Komplexität und die Steigerung der Geschwindigkeit. Der Nachteil von RISC ist die verringerte Befehlsdichte. Dies bedeutet, dass derselbe Code, der im RISC-ähnlichen Format ausgedrückt wird, mehr Befehle benötigt als der entsprechende CISC-Code.

Dieser Nebeneffekt hat keine große Bedeutung, wenn Ihre CPU mit der gleichen Geschwindigkeit wie der Arbeitsspeicher ausgeführt wird, oder zumindest, wenn beide mit einer angemessen ähnlichen Geschwindigkeit ausgeführt werden.

Gegenwärtig zeigt die Speichergeschwindigkeit im Vergleich zur CPU-Geschwindigkeit einen großen Unterschied bei den Takten. Aktuelle CPUs sind manchmal fünfmal oder schneller als der Hauptspeicher.

Dieser Stand der Technik begünstigt einen dichteren Code, den CISC bereitstellt.

Sie können argumentieren, dass Caches RISC-CPUs beschleunigen könnten. Das Gleiche gilt für CISC cpus.

Durch die Verwendung von CISC und Caches wird eine größere Geschwindigkeitsverbesserung erzielt als durch die Verwendung von RISC und Caches, da der Cachespeicher mit derselben Größe eine größere Auswirkung auf den von CISC bereitgestellten Code mit hoher Dichte hat.

Ein weiterer Nebeneffekt ist, dass RISC die Compiler-Implementierung schwieriger macht. Es ist einfacher, Compiler für CISC-CPUs zu optimieren. etc.

Intel weiß, was sie tun.

Dies ist so wahr, dass ARM einen Modus mit höherer Codedichte namens Thumb hat.

17
Jorge Aldo

Wenn Intel die Abwärtskompatibilität so lange beibehält (wir haben immer noch den virtuellen 8086-Modus neben dem 64-Bit-Modus), warum erlauben sie uns nicht, Programme zu kompilieren, damit sie die CISC-Anweisungen umgehen und den RISC-Core direkt verwenden? Dies eröffnet eine natürliche Möglichkeit, den heutzutage veralteten x86-Befehlssatz langsam aufzugeben (dies ist der Hauptgrund, warum sich Intel für die Verwendung des RISC-Kerns im Inneren entschieden hat, oder?).

Sie müssen sich den geschäftlichen Aspekt ansehen. Intel hat tatsächlich versucht, von x86 wegzukommen, aber es ist die Gans, die dem Unternehmen goldene Eier legt. XScale und Itanium konnten den Erfolg ihres x86-Kerngeschäfts nicht annähern.

Was Sie im Grunde bitten, ist, dass Intel seine Handgelenke aufschlitzt und dafür die Entwickler warmherzige Unschärfen einsteckt. X86 zu untergraben ist nicht in ihrem Interesse. Alles, was mehr Entwickler dazu bringt, sich nicht für x86 zu entscheiden, untergräbt x86. Das wiederum untergräbt sie.

15
Mike Thomsen

Die Antwort ist einfach. Intel entwickelt keine CPUs für Entwickler! Sie entwickeln sie für die Leute, die die Kauf- Entscheidungen treffen, was übrigens jedes Unternehmen auf der Welt tut!

Intel hat vor langer Zeit die Zusage gemacht, dass (aus vernünftigen Gründen) die CPUs abwärtskompatibel bleiben. Die Leute möchten wissen, dass beim Kauf eines neuen Intel-basierten Computers all ihrer aktuellen Software genauso ausgeführt wird wie auf ihrem alten Computer. (Obwohl hoffentlich schneller!)

Außerdem weiß Intel genau, wie wichtig dieses Engagement ist, weil sie einmal versucht haben, einen anderen Weg einzuschlagen. Genau wie viele Leute kennen Sie eine Itanium-CPU?!?

Sie werden es vielleicht nicht mögen, aber diese eine Entscheidung, beim x86 zu bleiben, hat Intel zu einem der bekanntesten Firmennamen der Welt gemacht!

4
geo

Die Antwort von @ jalf deckt die meisten Gründe ab, aber es gibt ein interessantes Detail, das darin nicht erwähnt wird: Der interne RISC-ähnliche Kern ist nicht dafür ausgelegt, einen Befehlssatz wie ARM/PPC/MIPS auszuführen. Die x86-Steuer wird nicht nur für die leistungshungrigen Decoder gezahlt, sondern bis zu einem gewissen Grad für den gesamten Kern. es ist nicht nur die x86-Befehlskodierung; Es ist jede Anweisung mit seltsamer Semantik.

Nehmen wir an, Intel hat einen Betriebsmodus erstellt, in dem der Anweisungsstrom nicht x86 war, sondern Anweisungen, die direkter auf uops abgebildet wurden. Stellen wir uns außerdem vor, dass jedes CPU-Modell ein eigenes ISA für diesen Modus hat, sodass sie weiterhin die Interna ändern können, wenn sie möchten, und sie mit einer minimalen Anzahl von Transistoren für die Anweisung aussetzen können. Dekodieren Sie dieses alternative Format.

Vermutlich verfügen Sie immer noch über die gleiche Anzahl von Registern, die dem x86-Architekturstatus zugeordnet sind, sodass x86-Betriebssysteme diese in Kontextumschaltungen ohne Verwendung des CPU-spezifischen Befehlssatzes speichern/wiederherstellen können. Aber wenn wir diese praktische Einschränkung verwerfen, könnten wir ein paar weitere Register haben, weil wir die verborgenen temporären Register verwenden können, die normalerweise für den Mikrocode reserviert sind1.


Wenn wir nur alternative Decoder haben, ohne Änderungen an späteren Pipelinestufen (Ausführungseinheiten), würde dies ISA) immer noch viele x86-Exzentrizitäten haben. Es wäre keine sehr schöne RISC-Architektur. Kein einzelner Befehl wäre sehr komplex, aber ein Teil der anderen Verrücktheit von x86 wäre immer noch vorhanden.

Beispiel: Links-/Rechtsverschiebungen lassen das Überlauf-Flag undefiniert, es sei denn, die Anzahl der Verschiebungen ist eins. In diesem Fall ist OF = die übliche Erkennung eines vorzeichenbehafteten Überlaufs. Ähnliche Verrücktheit dreht sich. Die freigelegten RISC-Anweisungen können jedoch flaggenlose Verschiebungen usw. bereitstellen (was die Verwendung von nur einem oder zwei der mehreren Uops ermöglicht, die normalerweise in einige komplexe x86-Anweisungen eingehen). Das ist also nicht wirklich das Hauptgegenargument.

Wenn Sie einen völlig neuen Decoder für eine RISC-ISA erstellen, können Sie Teile von x86-Anweisungen auswählen und als RISC-Anweisungen anzeigen lassen. Dies mindert die x86-Spezialisierung des Kerns etwas.


Die Befehlskodierung wäre wahrscheinlich nicht fest, da einzelne Uops viele Daten enthalten können. Viel mehr Daten als sinnvoll, wenn alle Insns gleich groß sind. Ein einzelnes mikrofusioniertes UOP kann einen 32-Bit-Direktoperanden und einen Speicheroperanden hinzufügen, der einen Adressierungsmodus mit 2 Registern und einer 32-Bit-Verschiebung verwendet. (In SnB und höher können nur Einzelregister-Adressierungsmodi mit ALU-Operationen mikrofusioniert werden.).

uops sind sehr groß und nicht sehr ähnlich zu Anweisungen mit fester Breite ARM=). Ein 32-Bit-Befehlssatz mit fester Breite kann nur 16-Bit-Befehle sofort gleichzeitig laden. Sofortiges Low-Half/Load-High-Instant-Paar. x86 muss das nicht tun, was dazu beiträgt, dass es nicht schrecklich ist, wenn nur 15 GP-Register die Möglichkeit einschränken, Konstanten in Registern beizubehalten. (15 ist eine große Hilfe für 7 Register.) Aber das erneute Verdoppeln auf 31 hilft viel weniger, ich glaube, es wurde eine Simulation gefunden. RSP ist normalerweise kein allgemeiner Zweck, also eher 15 GP-Register und ein Stapel.)


TL; DR-Zusammenfassung:

Auf jeden Fall läuft diese Antwort auf "Der x86-Befehlssatz ist wahrscheinlich der beste Weg, um eine CPU zu programmieren, die in der Lage sein muss, x86-Befehle schnell auszuführen", wirft aber hoffentlich etwas Licht auf die Gründe.


Interne UOP-Formate im Front-End und Back-End

Siehe auch Micro Fusion- und Adressierungsmodi für einen Fall von Unterschieden in Bezug auf die Darstellung der Front-End- und Back-End-UOP-Formate auf Intel-CPUs.

Fußnote 1 : Es gibt einige "versteckte" Register, die vom Mikrocode als temporäre Register verwendet werden können. Diese Register werden genau wie die x86-Architekturregister umbenannt, sodass Multi-UOP-Befehle nicht in der richtigen Reihenfolge ausgeführt werden können.

z.B. xchg eax, ecx auf Intel-CPUs dekodiert als 3 Uops ( warum? ), und unsere beste Vermutung ist, dass dies MOV-ähnliche Uops sind, die tmp = eax; ecx=eax ; eax=tmp;. In dieser Reihenfolge, weil ich die Latenz der dst-> src-Richtung bei ~ 1 Zyklus und umgekehrt bei 2 messe. Und diese Move-Ups sind keine regulären mov Anweisungen. Sie scheinen keine Kandidaten für die Eliminierung von Filmsequenzen ohne Latenz zu sein.

Siehe auch http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/ für eine Erwähnung des Versuchs, die PRF-Größe experimentell zu messen, und für physikalische Register, die zum Halten verwendet werden architektonischer Zustand, einschließlich versteckter Register.

Im Front-End nach den Decodern, jedoch vor der Ausgabe-/Umbenennungsphase, in der die Register in die physische Registerdatei umbenannt werden, werden im internen UOP-Format Registernummern verwendet, die den x86-Registernummern ähneln, jedoch über ausreichend Platz verfügen um diese versteckten Register anzusprechen.

Das UOP-Format unterscheidet sich innerhalb des außer Betrieb befindlichen Kerns (ROB und RS), auch bekannt als Back-End (nach der Ausgabe-/Umbenennungsphase). Die physischen Registerdateien int/FP jede hat 168 Einträge in Haswell , daher muss jedes Registerfeld in einem UOP breit genug sein, um so viele zu adressieren.

Da sich der Renamer in der HW befindet, ist es wahrscheinlich besser, ihn zu verwenden, als statisch geplante Anweisungen direkt an das Back-End zu senden. Wir würden also mit einer Reihe von Registern arbeiten, die so groß sind wie die x86-Architekturregister + Mikrocode-Temporäre, nicht mehr als das.

Das Back-End ist so konzipiert, dass es mit einem Front-End-Renamer zusammenarbeitet, der WAW/WAR-Gefahren vermeidet. Wir könnten es also nicht wie eine in-order-CPU verwenden, selbst wenn wir wollten. Es gibt keine Verriegelungen, um diese Abhängigkeiten zu erkennen. Das wird durch Ausgabe/Umbenennung gehandhabt.

Es wäre vielleicht ordentlich, wenn wir Uops in das Back-End einspeisen könnten, ohne den Engpass in der Ausgabe-/Umbenennungsphase (die engste Stelle in modernen Intel-Pipelines, z. B. 4-Wide bei Skylake vs. 4 ALU + 2 Load + 1 Store-Ports in das Backend). Aber wenn Sie das getan haben, können Sie Code nicht statisch einplanen, um die Wiederverwendung von Registern zu vermeiden und ein Ergebnis zu erzielen, das immer noch benötigt wird, wenn ein Cache-Miss eine Last für längere Zeit blockiert hat.

Wir müssen also so ziemlich alles in die Ausgabe-/Umbenennungsphase einspeisen und wahrscheinlich nur die Dekodierung umgehen, nicht den UOP-Cache oder IDQ. Dann bekommen wir normale OoO-Execs mit vernünftiger Gefahrenerkennung. Die Registerzuordnungstabelle ist nur dafür ausgelegt, 16 + einige Ganzzahlregister in die Ganzzahl-PRF mit 168 Einträgen umzubenennen. Wir konnten nicht erwarten, dass die Hardware einen größeren Satz logischer Register in dieselbe Anzahl physischer Register umbenennt. das würde eine größere RAT benötigen.

3
Peter Cordes