-
Die
vorliegende Erfindung bezieht sich allgemein auf die Ausführung von
Befehlen in Computersystemen, beispielsweise auf einen Trampolinmechanismus
zum Bewirken einer Steuerflussänderung in
einem Computersystem, um eine Verzweigung zu emulieren, wie z. B.
einen Trampolinmechanismus, der für die Wiederherstellung einer
Ausnahme verwendet wird, die durch vorgezogene oder spekulativ ausgeführte Befehle
verursacht wird.
-
Computersysteme
umfassen zumindest einen Prozessor und Speicher. Der Speicher speichert Programmbefehle,
Daten und ein Betriebssystem. Die Programmbefehle können einen
Kompilierer zum Kompilieren von Anwendungsprogrammen umfassen. Das
Betriebssystem steuert den Prozessor und den Speicher für Systembetriebe
und zum Ausführen der
Programmbefehle.
-
Ein „Basisblock" ist ein zusammenhängender
Satz von Befehlen, der durch Verzweigung und/oder Verzweigungsziele
begrenzt ist, die keine Verzweigungen oder Verzweigungsziele enthalten. Dies
impliziert, dass falls ein Befehl in einem Basisblock ausgeführt wird,
alle Befehle in dem Basisblock ausgeführt werden, d. h., die Befehle,
die in jedem Basisblock enthalten sind, werden auf einer Alles-oder-Nichts-Basis
ausgeführt.
Die Befehle in einem Basisblock werden für die Ausführung aktiviert, wenn Steuerung
zu dem Basisblock übertragen
wird, durch eine frühere
Verzweigung, die den Basisblock anvisiert („Anvisieren", wie es hier verwendet
wird, umfasst sowohl explizites Anvisieren über eine ausgeführte Verzweigung,
sowie auch implizites Anvisieren über eine nicht-ausgeführte Verzweigung.
-
Das
Vorhergehende impliziert, dass wenn eine Steuerung zu einem Basisblock
geleitet wird, alle Befehle in dem Rundblock ausgeführt werden müssen; falls
die Steuerung nicht zu dem Basisblock übertragen wird, werden keine
Befehle in dem Basisblock ausgeführt.
-
Somit
wird ein Steuerfluss zwischen Basisblöcken in Computerprogrammen
typischerweise mit Verzweigungen bewirkt. Eine Verzweigung bewertet typischerweise
eine Bedingung und ändert
den Steuerfluss entsprechend der Bedingung zu einem neuen Basisblock,
basierend auf dem Ergebnis der Bedingung.
-
In
einigen Fällen
ist es sehr unwahrscheinlich, dass eine Verzweigung ausgeführt wird,
wie z. B., wenn die Verzweigung als ein Ergebnis einer Fehlerbedingung
auftritt, die normalerweise während
einer normalen Programmausführung
nicht auftritt. Für solche
unwahrscheinliche Fälle
werden Verzweigungen typischerweise nach wie vor verwendet, um eine Steuerflussänderung
zu einem speziellen Basisblock zu bewirken, um die Fehlerbedingung
handzuhaben.
-
Ein
alternativer Lösungsansatz,
der zum Handhaben von Fehlerbedingungen verwendet wurde, ist, dass
die Fehlerbedingung eine Unterbrechung bewirkt. Die Unterbrechung
ruft im Allgemeinen einen anderen Steuerflussmechanismus auf und richtet
die Ausführung
zu einem speziellen Programm um, das als eine allgemeine Unterbrechungshandhabungsroutine
bezeichnet wird, die typischerweise Teil eines Betriebssystems ist.
Die allgemeine Unterbrechungshandhabungsroutine handhabt normalerweise
die Fehlerbedingung auf eine von zwei Weisen, abhängig von
dem Fehlerbedingungstyp.
-
In
dem ersten Szenario antwortet die allgemeine Unterbrechungshandhabungsroutine
auf die Fehlerbedingung und löst
das Problem im Zusammenhang mit der Fehlerbedingung. Das Programm, das
die Fehlerbedingung bewirkt hat, wird dann an dem Punkt neu gestartet,
wo das Programm auf den Fehler traf. In diesem ersten Szenario ist
die Fehlerbedingung allgemein über
Programme (z. B. eine Übersetzungsseitengriffspuffer-
(TLB-) Übersetzungsfehlschlagbedingung).
Daher wird die Auflösung
der Fehlerbedingung vollständig durch
die allgemeine Unterbrechungshandhabungsroutine durchgeführt. Die
allgemeine Unterbrechungshandhabungsroutine löst die Fehlerbedingung auf
die gleiche Weise auf, unabhängig
davon, welche Funktion das Programm ausführt, das auf die Fehlerbedingung
trifft.
-
Bei
dem zweiten Szenario bestimmt die allgemeine Unterbrechungshandhabungsroutine,
dass das Programm, das auf die Fehlerbedingung trifft, die Fehlerbedingung
handhaben muss. Typischerweise liefert das Programm Informationen
an die allgemeine Unterbrechungshandhabungsroutine, um anzuzeigen,
dass das Programm selbst die Fehlerbedingung handhaben soll. Außerdem zeigt
das Programm typischerweise an, welcher Teil des Programms auf eine
Fehlerbedingung hin aufgerufen werden sollte. Nachdem die allgemeine
Unterbrechungshandhabungsroutine bestimmt, dass die allgemeine Unterbrechungshandhabungsroutine
die Fehlerbedingung nicht selbst handhaben kann, und dass das Programm,
das die Fehlerbedingung erfahren hat, angezeigt hat, dass das Programm
die Fehlerbedingung handhaben soll, erstellt die allgemeine Unterbrechungshandhabungsroutine
typischerweise eine Datenstruktur und ruft die eigene spezifische Handhabungsroutine
des Programms auf. Die Datenstruktur, die durch die allgemeine Unterbrechungshandhabungsroutine
aufgebaut wird, ist typischerweise sehr groß, weil die allgemeine Unterbrechungshandhabungsroutine
keine ausreichenden Informationen hat, um zu bestimmen, welche Datenelemente
erforderlich sind, um die Fehlerbedingung handzuhaben. Die Fehlerbedingung
wird dann durch das Programm direkt gehandhabt. Nachdem das Programm
die Handhabung der Fehlerbedingung abschließt, wird das Betriebssystem
erneut aufgerufen, um das Programm an dem Punkt neu zu starten,
wo der Fehler auftrat. Dieser Lösungsansatz
zum Handhaben einer Fehlerbedingung wird als ein Signalhandhabungsroutinelösungsansatz
bezeichnet, und die allgemeine Unterbrechungshandhabungsroutine wird
als eine Signalhandhabungsroutine bezeichnet.
-
Zusammengefasst,
wenn Änderungen
bei dem Steuerfluss auf der Basis von Bedingungen bewirkt werden,
die relativ unregelmäßig sind
und die eine spezielle Handhabung erfordern (d. h. keine allgemeine
Handhabung), gibt es zwei Grundlösungsansätze, die
verwendet wurden, um einen Steuerfluss zu bewirken. Bei dem ersten
Lösungsansatz wird
eine Verzweigung zu dem spezialisierten Handhabungsroutineteil des
Programms hergestellt. Bei dem zweiten Lösungsansatz wird eine allgemeine
Signalhandhabungsroutine, die typischerweise Teil des Betriebssystems
ist, über
eine Unterbrechung des Steuerflusses aufgerufen, und die allgemeine
Signalhandhabungsroutine erstellt eine Datenstruktur und ruft den
spezialisierten Handhabungsroutineteil des Programms auf.
-
Diese
beiden Grundlösungsansätze haben für einfache
skalare Prozessoren im Allgemeinen gut funktioniert. Jeder Lösungsansatz
umfasst im Allgemeinen einen gewissen Befehl, wie z. B. eine bedingte
Verzweigung oder einen anderen Befehl, der eine Unterbrechung auf
der Basis einer Bedingung bewirkt. Bei früheren Computersystemen war
der Mehraufwand für
bedingte Verzweigungsbefehle ähnlich wie
der Mehraufwand für
andere Befehle, die eine Unterbrechung auf der Basis einer Bedingung
bewirken.
-
Der
Mehraufwand für
Verzweigungsbefehle hat sich jedoch mit aktuellen Computersystemen
wesentlich erhöht
und wird sich wahrscheinlich mit zukünftigen Computersystemen weiter
erhöhen.
In vielen Computersystemen werden einige aufwändige Verzweigungsfehlvorhersagen
vermieden, wenn Programme anzeigen, dass die Verzweigung unwahrscheinlich
ist und der Prozessor bezieht dies in eine Verzweigungsvorhersage
ein. Trotzdem, während Computersysteme
umfangreicher werden, wird der Bedarf zum Ausführen mehrerer Verzweigungen
in jedem Zyklus höher.
Das Ausführen
mehrerer Verzweigungen in jedem Zyklus erfordert zusätzliche Ressourcen
und/oder verkompliziert die Verzweigungsvorhersage, was die Genauigkeit
der Vorhersage verringert. Daher erhöhen sich die effektiven Kosten
eines Verzweigungsbefehls für
eine relativ seltene Bedingung.
-
Andererseits
werden nun Optimierungen verwendet, um den höchstwahrscheinlichsten Pfad eines
Programms effektiv als einzelne Einheit zu behandeln. Weniger wahrscheinliche
Pfade des Programms werden ähnlich
wie Fehlerbedingungen behandelt. Ein Vorteil dieser Optimierungstechnik
ist, dass dieselbe eine sehr viel bessere Zeitplanung von Hardwareressourcen
auf dem höchstwahrscheinlichsten
Programmpfad ermöglicht.
Diese Art von weniger wahrscheinlicher Pfad-„Fehlerbedingung" ist unregelmäßig, aber
nicht annähernd
so unregelmäßig wie
die traditionelle Art von Fehlerbedingung, die durch den Signalhandhabungsroutinelösungsansatz gehandhabt
wird. Der Signalhandhabungsroutinelösungsansatz umfasst eine riesige
Menge an Mehraufwand und ist nur effektiv, wenn die Wahrscheinlichkeit
des Fehlers nicht nur klein, sondern minimal ist.
-
Angesichts
der obigen Ausführungen
gibt es einen Bedarf an einem verbesserten Mechanismus zum Ändern eines
Steuerflusses ohne Verzweigungen für unregelmäßige, aber nicht unendlich
seltene Situationen. Ein Computersystem, das einen solchen verbesserten
Steuerflussänderungsmechanismus verwendet,
soll eine bessere Codezeitplanung ermöglichen, um Falschvorhersageprobleme
zu vermeiden, und um Komplikationen zu vermeiden, die sich aus mehreren
Verzweigungen pro Zyklus ergeben. Ferner gibt es einen Wunsch, dass
ein solcher verbesserter Steuerflussänderungsmechanismus sehr viel
schneller ist, wenn er aufgerufen wird, als der Signalhandhabungsroutinelösungsansatz
mit hohem Mehraufwand, so dass die Leistungskosten des verbesserten
Steuerflussänderungsmechanismus nicht
wesentlich sind.
-
Der
Akt des Ausführens
oder Spezifizierens der Ausführung
eines Befehls, bevor die Steuerung zu dem Befehl geleitet wurde,
wird als „Spekulation" bezeichnet. Eine
Spekulation, die durch den Prozessor zur Programmlaufzeit durchgeführt wird,
wird als „dynamische
Spekulation" bezeichnet,
während
eine Spekulation, die durch den Kompilierer spezifiziert wird, als „statische
Spekulation" bezeichnet
wird. Dynamische Spekulation ist im Stand der Technik bekannt. Obwohl
der Großteil
des Stands der Technik nicht auf statische Spekulation basiert oder
sich auf diese bezieht, sind in jüngster Zeit einige Verweise auf
statische Spekulation aufgetaucht.
-
Zwei
Befehle werden als „unabhängig" bezeichnet, wenn
einer nicht das Ergebnis des Anderen erfordert; wenn ein Befehl
das Ergebnis des Anderen erfordert, werden die Befehle als „abhängig" bezeichnet. Unabhängige Befehle
können
parallel ausgeführt
werden, während
abhängige
Befehle auf serielle Weise ausgeführt werden müssen. Die
Programmleistungsfähigkeit
wird verbessert durch Identifizieren unabhängiger Befehle und Ausführen von
so vielen derselben wie möglich
auf parallele Weise. Die Erfahrung zeigt, dass mehr unabhängige Befehle
gefunden werden können
durch Suchen über
mehrere Basisblöcke,
als gefunden werden können
durch Suchen nur innerhalb einzelner Basisblöcke. Eine gleichzeitige Ausführung von
Befehlen von mehreren Basisblöcken
erfordert jedoch Spekulation.
-
Das
Identifizieren und Zeitplanen von unabhängigen Befehlen und dadurch
das Erhöhen
der Leistungsfähigkeit
ist eine der Hauptaufgaben von Kompilierern und Prozessoren. Der
Trend bei Kompilierer- und Prozessorentwurf ist es, den Umfang der Suche
nach unabhängigen
Befehlen in jeder nachfolgenden Generation zu erhöhen. In
herkömmlichen Befehlssätzen kann
ein Befehl, der eine Ausnahme erzeugen kann, nicht durch den Kompilierer
spekuliert werden, da, falls der Befehl eine Ausnahme verursacht,
das Programm fehlerhaftes Verhalten zeigen kann. Dies beschränkt den
nutzbaren Umfang der Suche des Kompilierers nach unabhängigen Befehlen
und macht es notwendig, dass Spekulation bei Programmlaufzeit durch
den Prozessor über
dynamische Spekulation durchgeführt
wird. Eine dynamische Spekulation erfordert jedoch eine wesentliche Menge
an Hardwarekomplexität,
die sich exponentiell erhöht
mit der Anzahl von Basisblöcken, über die dynamische
Spekulation angelegt wird – dies
legt eine praktische Begrenzung an den Umfang der dynamischen Spekulation
auf. Im Gegensatz dazu ist der Umfang, über den der Kompilierer nach
unabhängigen
Befehlen suchen kann, sehr viel größer – potentiell das gesamte Programm.
Ferner, sobald der Kompilierer entworfen wurde, um statische Spekulation über eine
einzelne Basisblockgrenze durchzuführen, wird nur sehr wenig zusätzliche
Komplexität bewirkt
durch statisches Spekulieren über
mehrere Basisblockgrenzen.
-
Falls
eine statische Spekulation durchgeführt werden soll, müssen mehrere
Probleme gelöst
werden, eines der wichtigen ist die Handhabung von Ausnahmebedingungen,
die durch statisch spekulierte Befehle angetroffen werden. Da, wie
es oben angemerkt ist, Ausnahmen zu spekulativen Befehlen nicht
zum Zeitpunkt der Ausführung
der Befehle geliefert werden können,
wird ein kompilierer-sichtbarer Mechanismus gewünscht, um die Lieferung der
Ausnahmen zu verschieben, bis die Steuerung zu dem Basisblock übertragen
wird, von dem die Befehle spekuliert wurden (der als der „Ursprungsbasisblock" bekannt ist). Mechanismen,
die eine ähnliche
Funktion durchführen,
gibt es im Stand der Technik zum Verschieben und späteren Liefern
von Ausnahmen zu dynamisch spekulierten Befehlen. Durch Definition
sind die Mechanismen jedoch für
den Kompilierer nicht sichtbar und können daher nicht durch den Kompilierer
manipuliert werden, um bei der kompilierer-angewiesenen Spekulation
eine Rolle zu spielen. Kein bekanntes Verfahren oder keine bekannte
Vorrichtung zum Verschieben und späteren Liefern von schwerwiegenden
und nicht-schwerwiegenden Ausnahmen zu statisch spekulierten Befehlen
wurde im Stand der Technik ermöglicht.
Begrenzte Formen statischer Spekulation gibt es jedoch im Stand
der Technik: (1) Die Formen umfassen keine Verschiebung und spätere Wiederherstellung
von Ausnahmebedingungen, und (2) die Formen ermöglichen keine statische Spekulation über die
Breite und den Umfang der vorliegenden Erfindung.
-
Wenn
daher eine statische Spekulation durchgeführt wird, gibt es in der Technik
einen Bedarf an einem Mechanismus zum Handhaben von Ausnahmen zu
spekulativen Befehlen, so dass alle Nebeneffekte der spekulativen
Befehle für
den Programmierer nicht sichtbar sind. Ferner sollte der Mechanismus
für so
viele Formen von statischer Spekulation wie möglich gelten.
-
Es
gibt auch einen Bedarf an einem Mechanismus zum Erreichen einer
höheren
Leistung in Computersystemen durch Ermöglichen der Ausführung von
so vielen unabhängigen
Befehlen parallel wie möglich.
Dies ist wünschenswert,
selbst wenn es eine Möglichkeit
gibt, dass ein zweiter Befehl, sowie eine davon abhängige Berechnung,
an Daten arbeiten kann, die von der Ausführung eines ersten Befehls
abhängig
sein können.
-
Es
gibt auch einen Bedarf an einem verbesserten Mechanismus in Computersystemen
für die Wiederherstellung
einer Ausnahme, die durch vorgezogene oder spekulativ ausgeführte Befehle
bewirkt wird, die einen verbesserten Mechanismus zum Bewirken einer
Steuerflussänderung
umfasst, die keine Verzweigungen umfasst, um eine bessere Codezeitplanung
zu ermöglichen,
um Falschvorhersageprobleme zu vermeiden, und um Komplikationen
zu vermeiden, die sich aus mehreren Verzweigungen pro Zyklus ergeben.
Solch ein verbesserter Wiederherstellungsmechanismus ist erwünscht, der
relativ schnell ist, wenn er aufgerufen wird, so dass er die Leistungsfähigkeit
der Wiederherstellung des Computersystems von der Ausnahme verbessert,
die durch vorgezogene oder spekulativ ausgeführte Befehle bewirkt wurde.
-
Die
Europäische
Patentanmeldung
EP0605872 offenbart
einen Prozess, der Befehle spekulativ ausführt. Wenn eine Unterbrechung
vor dem Abschluss einer Verzweigung auftritt, wird der Ausgabeversionswert
ersetzt durch den Abschlussversionswert, um das System zu einem
Zustand vor der Spekulationsausführung
wiederherzustellen.
-
Die
vorliegende Erfindung schafft ein verbessertes Computersystem. Die
bevorzugten Ausführungsbeispiele
sind entworfen, um eines oder mehrere der oben beschriebenen Probleme
zu adressieren.
-
Gemäß einem
Aspekt der vorliegenden Erfindung ist ein Computersystem gemäß Anspruch
1 vorgesehen.
-
Falls
die in den Ansprüchen
spezifizierte Bedingung falsch ist, wird vorzugsweise der normale Steuerfluss
des Programms fortgesetzt.
-
Gemäß einem
weiteren Aspekt der vorliegenden Erfindung ist ein Verfahren zum
Ausführen von
Befehlen in einem Computersystem gemäß Anspruch 8 vorgesehen.
-
Das
bevorzugte Ausführungsbeispiel
liefert ein Verfahren und ein Computersystem, das einen Speicher
und einen Prozessor umfasst. Der Speicher speichert ein Programm
und eine Unterbrechungshandhabungsroutine. Das Programm weist Befehle auf,
die einen Trampolinprüfbefehl
und eine Spezialhandhabungsroutine zum Handhaben einer Unterbrechung
umfassen. Der Prozessor führt
das Programm und die Unterbrechungshandhabungsroutine aus. Der Prozessor
umfasst einen Befehlszeiger, der eine Speicherposition eines aktuell
ausführenden Befehls
anzeigt. Der Prozessor führt
den Trampolinprüfbefehl
aus, der eine Bedingung prüft,
und falls die Bedingung wahr ist, die Unterbrechung bewirkt und eine
Adressverschiebung liefert. Die Unterbrechungshandhabungsroutine
spricht auf die Unterbrechung an und startet die Ausführung des
Programms neu an einem Neustartpunkt, der eine Speicherstelle der
Spezialhandhabungsroutine anzeigt. Der Neustartpunkt ist gleich
einer Summe der Adressverschiebung und eines Werts des Befehlszeigers
zum Zeitpunkt der Unterbrechung.
-
Bei
einem Ausführungsbeispiel
addiert die Unterbrechungshandhabungsroutine die Adressverschiebung
zu dem Wert des Befehlszeigers zum Zeitpunkt der Unterbrechung,
um den Neustartpunkt ansprechend auf die Unterbrechung zu erhalten.
Bei einem alternativen Ausführungsbeispiel
umfasst der Prozessor Hardware zum Hinzufügen der Adressverschiebung
zu dem Wert des Befehlszeigers zum Zeitpunkt der Unterbrechung,
um den Neustartpunkt und ein Unterbrechungssteuerregister zum Erfassen
des Neustartpunkts zu erhalten. Bei dem alternativen Ausführungsbeispiel
erhält
die Unterbrechungshandhabungsroutine den Neustartpunkt von dem Unterbrechungssteuerregister
ansprechend auf die Unterbrechung.
-
Bei
einem Ausführungsbeispiel
umfasst der Prozessor ein Unterbrechungssteuerregister zum Erfassen
der Adressverschiebung. Bei einem Ausführungsbeispiel speichert der
Speicher eine Unterbrechungsvektortabelle, die einen Unterbrechungsvektor
zum Liefern von Informationen umfasst, die sich auf die Unterbrechung
beziehen. Der Unterbrechungsvektor wird vorzugsweise nicht gemeinschaftlich
verwendet mit anderen Unterbrechungen, so dass die Unterbrechungshandhabungsroutine
keine zusätzliche
Decodiersoftware erfordert, um den Grund der Unterbrechung zu bestimmen.
Bei einem Ausführungsbeispiel
speichert der Speicher ein Betriebssystem zum Steuern des Prozessors
und des Speichers, und die Unterbrechungshandhabungsroutine ist
Teil des Betriebssystems.
-
Falls
bei einem Ausführungsbeispiel
die Bedingung falsch ist, wird der normale Steuerfluss des Programms
fortgesetzt.
-
Bei
einem Ausführungsbeispiel
führt der
Prozessor die spezielle Handhabungsroutine des Programms aus, um
die Unterbrechung handzuhaben. Nachdem die spezielle Handha bungsroutine
die Unterbrechung handhabt, führt
der Prozessor einen Verzweigungsbefehl aus, um die Verzweigung zurück zu einem
Teil des Programms zu verzweigen, das zum Zeitpunkt der Unterbrechung
ausgeführt wurde.
-
Bei
einem Ausführungsbeispiel
umfassen die Programmbefehle auch einen Speicherbefehl und einen
Ladebefehl, der vor dem Speicherbefehl geplant ist. Die Bedingung
ist wahr, falls der Speicherbefehl und der Ladebefehl auf eine gemeinsame
Stelle in dem Speicher zugreifen. Bei einem Ausführungsbeispiel umfassen die
Programmbefehle ferner zumindest einen Berechnungsbefehl, der von Daten
abhängig
ist, die durch den Ladebefehl gelesen werden. Der zumindest eine
Berechnungsbefehl ist vor dem Speicherbefehl geplant. Die spezielle Handhabungsroutine
umfasst Wiederherstellungscode, der Code für eine Wiederausführung des
Ladebefehls und des zumindest einen Berechnungsbefehls umfasst.
-
Bei
einem Ausführungsbeispiel
umfassen die Programmbefehle auch einen ersten Befehl und einen
zweiten Befehl. Der zweite Befehl ist vor dem ersten Befehl geplant.
Die Bedingung ist wahr, falls der zweite Befehl an Daten arbeitet,
die von der Ausführung
des ersten Befehls abhängen.
Die spezielle Handhabungsroutine umfasst Wiederherstellungscode,
der Code für
eine Wiederausführung
des zweiten Befehls umfasst.
-
Bei
einem Ausführungsbeispiel
umfassen die Programmbefehle auch zumindest einen Befehl, der als
spekulativ gekennzeichnet ist. Die Bedingung ist wahr, falls die
Integrität
der Ausführung
von zumindest einem Befehl, der als spekulativ gekennzeichnet ist,
nicht verifiziert ist. Die spezielle Handhabungsroutine umfasst
Wiederherstellungscode, der Code für die Wiederausführung des
zumindest einen Befehls umfasst, der als spekulativ gekennzeichnet
ist.
-
Bei
einem Ausführungsbeispiel
sind die Programmbefehle in einer Mehrzahl von Basisblöcken organisiert.
Jeder Basis block umfasst einen Satz von zusammenhängenden
Befehlen. Die Programmbefehle umfassen einen ersten Befehl, der
einem ersten Basisblock zugeordnet ist und sind in der Lage, während der
Ausführung
des Programms eine Ausnahme zu erzeugen. Der erste Befehl ist außerhalb
des ersten Basisblocks und vor zumindest einem Befehl geplant, der
dem ersten Basisblock vorausgeht. Die Bedingung ist wahr, falls
der erste Befehl, der eine Ausnahme erzeugt hat. Bei einem Ausführungsbeispiel
wird der Trampolinprüfbefehl
in dem ersten Basisblock geplant. Die spezielle Handhabungsroutine umfasst
Wiederherstellungscode, der Code für die Wiederausführung des
ersten Befehls umfasst.
-
Bei
einem Ausführungsbeispiel
umfassen die Programmbefehle auch einen ersten spekulativen Befehl,
der in der Lage ist, während
der Ausführung
des ersten spekulativen Befehls eine Befehlsausnahmebedingung zu
erfahren. Der erste spekulative Befehl verschiebt die Signalisierung
einer Befehlsausnahme, wenn die Befehlsausnahmebedingung anfangs
erfasst wird und schließt
die Ausführung
ab, ohne die Befehlsausnahme zu signalisieren. Die Bedingung ist
wahr, falls die Befehlsausnahme während der Ausführung des
ersten spekulativen Befehls erfasst wurde. Die spezielle Handhabungsroutine
umfasst Wiederherstellungscode, der Code für die Wiederausführung des
ersten spekulativen Befehls umfasst.
-
Das
bevorzugte Ausführungsbeispiel
des Computersystems umfasst einen Trampolinmechanismus zum Ändern des
Steuerflusses, um einen Verzweigungsbefehl zu emulieren. Der Trampolinmechanismus
ermöglicht
eine bessere Codezeitplanung, vermeidet Verzweigungsfehlvorhersageprobleme
und vermeidet Komplikationen, die sich aus mehreren Verzweigungen
pro Zyklus ergeben. Der Trampolinmechanismus ist viel schneller,
wenn er aufgerufen wird, als der Signalhandhabungsroutinelösungsansatz
mit hohem Mehraufwand, daher sind die Leistungskosten des Trampolinmechanismus
nicht wesentlich. Daher ist der Trampolinmechanismus ziemlich nützlich zum
Handhaben von Bedingungen, die unregelmäßig wahr sind, aber so gut
wie nie wahr sind. Darüber
hinaus kann der Trampolinmechanismus verwendet werden für die Wiederherstellung
einer Ausnahme, die durch vorgezogene oder spekulativ ausgeführte Befehle
bewirkt wird.
-
Ausführungsbeispiele
der vorliegenden Erfindung werden nachfolgend mit Bezugnahme auf
die beiliegenden Zeichnungen beispielhaft beschrieben. Es zeigen:
-
1 ein
Blockdiagramm eines Universalcomputers, auf dem Ausführungsbeispiele
der vorliegenden Erfindung implementiert werden können;
-
2 ein
Flussdiagramm, das einen Betrieb eines Trampolinmechanismus zum
Bewirken einer Steuerflussänderung
in dem Computersystem von 1 darstellt;
-
3 ein
Flussdiagramm, das ein Ausführungsbeispiel
des Betriebs der Unterbrechungshandhabungsroutine darstellt, die
bei der in 2 dargestellten Trampolinmechanismusoperation
verwendet wird;
-
4 eine
Originalcodesequenz, die drei Basisblöcke umfasst;
-
5 eine
geplante Codesequenz, die sich aus dem Planen der Ursprungscodesequenz
von 2 unter Verwendung statischer Spekulation gemäß einem
Ausführungsbeispiel
der vorliegenden Erfindung ergibt;
-
6 eine
Originalcodesequenz, die einen Speicherspeicherbefehl gefolgt von
einem Speicherladebefehl umfasst;
-
7 eine
geplante Codesequenz, die sich aus dem Planen der Ursprungscodesequenz
von 4 unter Verwendung von statischer Datenspekulation
ergibt, um den Ladebefehl gemäß einem
Ausführungsbeispiel
der vorliegenden Erfindung vorzuziehen;
-
8 ein
Flussdiagramm eines Prozesses zum Vorziehen eines Ladebefehls und
Befehle, die von demselben abhängen,
vor einem Speicherbefehl gemäß einem
Ausführungsbeispiel
der vorliegenden Erfindung;
-
9 ein
Flussdiagramm eines Prozesses zum Ausführen vorgezogener Ladebefehle
zur Laufzeit gemäß einem
Ausführungsbeispiel
der vorliegenden Erfindung; und
-
10 ein
Beispiel einer vorgezogenen Ladeadresstabelle gemäß einem
Ausführungsbeispiel der
vorliegenden Erfindung.
-
Ein
Ausführungsbeispiel
der vorliegenden Erfindung bezieht sich auf einen Trampolinmechanismus
zum Bewirken einer Steuerflussänderung
in einem Computersystem, um einen Verzweigungsbefehl zu emulieren.
Ein Ausführungsbeispiel
der Erfindung bezieht sich auf ein Verfahren und eine Vorrichtung
zum Ermöglichen
einer Wiederherstellung von Problemen, die während der Ausführung von
vorgezogenen oder spekulierten Befehlen aufgetreten sind, und insbesondere
auf einen Trampolinmechanismus zum Bewirken einer Steuerflussänderung
in einem Computersystem während
der Wiederherstellung einer Ausnahme, die durch vorgezogene oder spekulativ
ausgeführte
Befehle bewirkt wird. Diese Aspekte der vorliegenden Erfindung können mit
jedem Computersystemtyp verwendet werden. Ein Beispiel eines solchen
Computersystems ist ein Universalcomputersystem 50, das
in 1 dargestellt ist. Das Universalcomputersystem 50 umfasst
einen Prozessor 52, ein Eingabegerät 54, ein Ausgabegerät 56 und
einen Speicher 58, die durch einen Bus 60 miteinander
verbunden sind. Der Speicher 58 umfasst einen Primärspeicher 62 (d.
h. einen schnellen flüchtigen
Speicher, wie z. B. einen dynamischen Halbleiterspeicher) und einen
Sekundärspeicher 64 (d.
h. einen nicht-flüchtigen
Speicher, wie z. B. Flash-Speicher und Magnetplatten). Der Speicher 58 speichert
ein oder mehrere Programme 66, die auf dem Prozessor 52 ausgeführt werden.
Ein Betriebssystem (OS) 68 ist in dem Speicher 58 gespeichert und
steuert den Prozessor 52 und den Speicher 58 für Systemoperationen
und zum Ausführen
von Programmen 66, die in dem Speicher 58 gespeichert sind.
-
Die
Programme 66 steuern das Universalcomputersystem 50,
wenn sie durch den Prozessor 52 ausgeführt werden. Programme 66 können einen Kompilierer
umfassen, dessen Funktion nachfolgend in Verbindung mit 6 beschrieben
ist.
-
Der
Prozessor 52 umfasst einen Anwendungsregistersatz 70 und
einen Systemregistersatz 72. Ein Architekturzustand des
Computersystems 50 ist durch den Anwendungsregistersatz 70,
den Systemregistersatz 72 und den Speicher 58 dargestellt. Der
Anwendungsregistersatz 70 umfasst Register, die für Anwendungsprogramme
verfügbar
sind, die in dem Speicher 58 gespeichert sind. Der Systemregistersatz 72 liefert
Systemregisterressourcen für
Prozesssteuerung, Unterbrechungshandhabung, Schutz, Debugging, Leistungsüberwachung
und dergleichen. Der Systemregistersatz 72 ist normalerweise
nur für
das Betriebssystem 68 sichtbar.
-
Beispielregister,
die in dem Anwendungsregistersatz 70 enthalten sein können, umfassen
allgemeine Register, Gleitpunktregister, Vergleichsergebnisregister,
Verzweigungsinformationsregister, Aktueller-Rahmen-Markierungen,
Prozessidentifizierer, Benutzermasken und eine Anwendungsregisterdatei. Der
Anwendungsregistersatz 70 umfasst insbesondere einen Befehlszeiger 71,
der die Adresse zu dem aktuell ausführenden Befehl oder die Adresse
eines Befehlsbündels
speichert, das den aktuell ausführenden
Befehl enthält.
-
Beispielregister,
die in dem Systemregistersatz 72 enthalten sein können, umfassen
Regionsregister, Schutzschlüsselregister,
Fehlerbeseitigungs-Unterbrechungspunktregister, maschinenspezifische
Register, ein Prozessorstatusregister und einen Übersetzungsseitengriffspuffer
(TLB). Der Systemregistersatz 72 umfasst insbesondere Steuerregister 74,
die mehrere Register enthalten, die den Zustand des Prozessors 52 bei
einer Unterbrechung erfassen, systemweite Merkmale aktivieren und
globale Prozessorparameter für
Unterbrechungen und Speicherverwaltung spezifizieren.
-
Die
Steuerregister 74 umfassen insbesondere Unterbrechungssteuerregister 75,
die Informationen zum Zeitpunkt einer Unterbrechung aufzeichnen und
durch Unterbrechungshandhabungsroutinen verwendet werden, um die
gegebene Unterbrechung zu verarbeiten. Unterbrechungssteuerregister 75 umfassen
insbesondere ein Unterbrechungszwischen- (IIM-) Register 76,
das Adressverschiebung an einer Unterbrechung gemäß der vorliegenden
Erfindung erfasst und die Adressverschiebung für eine Unterbrechungshandhabungsroutine 82 in
dem Betriebssystem 68 verfügbar macht. Der Betrieb des
IIM-Registers 76,
wie er sich auf dem Trampolinmechanismus zum Bewirken einer Steuerflussänderung
in dem Computersystem 50 bezieht, wird nachfolgend näher beschrieben.
Die Steuerregister 74 umfassen auch insbesondere ein Unterbrechungsvektoradress-
(IVA-) Register 78, das die Position einer Unterbrechungsvektortabelle 80 spezifiziert,
die in dem Speicher 58 gespeichert ist, die Unterbrechungsvektoren
speichert, die Informationen liefern, die sich auf entsprechende
Unterbrechungen beziehen.
-
Es
sollte klar sein, dass das Computersystem 50 von 1 lediglich
zu Darstellungszwecken geliefert wird, und dass die Ausführungsbeispiele
der vorliegenden Erfindung, die nachfolgend beschrieben sind, auf
zahlreichen anderen Computersystemtypen und -konfigurationen implementiert
sein können.
-
Das
Computersystem 50 umfasst einen Trampolinmechanismus gemäß der vorliegenden
Erfindung zum Bewirken einer Steuerflussänderung zum Emulieren eines
Verzweigungsbefehls. Der Trampolinmechanismus umfasst einen Trampolinprüfbefehl,
der durch das Computersystem 50 verwendet wird, um eine
Bedingung zu prüfen
und eine Unterbrechung zu bewirken, falls die Bedingung wahr ist.
Der Trampolinprüfbefehl
liefert auch eine Adressverschiebung, die spezifiziert, wo auszuführen ist,
in dem Fall, dass die Bedingung wahr ist. Bei einem Ausführungsbeispiel
wird der Trampolinprüfbefehl
verwendet, um eine Steuerflussänderung
zu bewirken, auf der Basis von Bedingungen, die typischerweise wahr
sind für
unregelmäßige, aber
nicht unendlich seltene Situationen.
-
Der
Trampolinmechanismus des Computersystems 50 umfasst einen
Unterbrechungsvektor für die
gegebene Unterbrechungsbedingung, wie z. B. den Unterbrechungsvektor 81 in
der Unterbrechungsvektortabelle 80. Bei einem Ausführungsbeispiel
wird der Unterbrechungsvektor 81 nicht gemeinschaftlich
verwendet mit anderen Unterbrechungen, so dass die Unterbrechungshandhabungsroutine 82 zum
Implementieren des Trampolinmechanismus keine zusätzliche
Decodiersoftware erfordert, um die Ursache der Unterbrechung zu
bestimmen.
-
Der
Trampolinmechanismus des Computersystems 50 umfasst das
IIM-Register 76 der Steuerregister 74, um die
Adressverschiebung zu erfassen, die durch den Trampolinprüfbefehl
geliefert wird, wenn die Unterbrechungsbedingung wahr ist. Das IIM-Register 76 macht
die Adressverschiebung für eine
Unterbrechungshandhabungsroutine verfügbar, wie z. B. die Unterbrechungshandhabungsroutine 82. Bei
einem Ausführungsbeispiel
ist die Unterbrechungshandhabungsroutine 82 Teil des Betriebssystems 68.
Die Unterbrechungshandhabungsroutine 82 fügt die Adressverschiebung,
die in dem IIM-Register 76 gespeichert ist, dem Wert des
Befehlszeigers 71 (d. h. dem Programmzähler) zum Zeitpunkt der Unterbrechung
hinzu, um einen Neustartpunkt zu erhalten. Die Unterbrechungshand habungsroutine 82 startet
dann die Ausführung
an dem Neustartpunkt neu.
-
Ein
Ausführungsbeispiel
eines Betriebs eines Trampolinmechanismus zum Bewirken einer Steuerflussänderung
in dem Computersystem 50 ist allgemein bei 100 in
Flussdiagrammform in 2 dargestellt. Bei Schritt 102 prüft der Trampolinprüfbefehl,
ob eine Bedingung wahr ist. Falls die Bedingung falsch ist, wird
bei Schritt 104 der normale Steuerfluss fortgesetzt. Falls
die Bedingung, die durch den Trampolinprüfbefehl geprüft wird,
wahr ist, bewirkt der Trampolinprüfbefehl bei Schritt 106 eine
Unterbrechung. Bei Schritt 108 liefert der Trampolinprüfbefehl
eine Adressverschiebung. Bei Schritt 110 erfasst das IIM-Register 76 die
Adressverschiebung, die durch den Trampolinprüfbefehl in Schritt 108 geliefert wird.
-
Bei
Schritt 112 addiert die Unterbrechungshandhabungsroutine 82 die
Adressverschiebung, die in dem IIM-Register 76 gespeichert
ist, zu dem Wert des Befehlszeigers 71, zum Zeitpunkt der
Unterbrechung, um einen Neustartpunkt zu liefern. Bei Schritt 114 startet
die Unterbrechungshandhabungsroutine 82 die Ausführung an
dem Neustartpunkt neu, der bei Schritt 112 berechnet wird.
Bei einem alternativen Ausführungsbeispiel
addiert die Hardware in dem Prozessor 52 die Adressverschiebung
zu dem Wert des Befehlszeigers 71, zum Zeitpunkt der Unterbrechung,
um den Neustartpunkt zu erhalten, und ein Unterbrechungssteuerregister
der Unterbrechungssteuerregister 75 erfasst den Neustartpunkt.
Bei diesem alternativen Ausführungsbeispiel
muss die Unterbrechungshandhabungsroutine 82 keine Berechnungen
durchführen,
um den Neustartpunkt zu erhalten, und startet die Ausführung einfach
neu an dem Neustartpunkt, der in dem Unterbrechungssteuerregister
aufgenommen ist.
-
Bei
Schritt 116 handhabt die eigene spezielle Handhabungsroutine
des Programms die Unterbrechungsbedingung. Nachdem die eigene spezielle Handhabungsroutine
des Programms die Unterbrechungsbedingung handhabt, bei Schritt 118,
wird eine Verzweigung zurück
zu dem Hauptprogrammsteuerfluss durchgeführt und die Befehlsausführung wird
fortgesetzt.
-
Daher
emuliert der Trampolinprüfbefehl
effektiv einen Verzweigungsbefehl aus Sicht des Programmierers.
Aus Sicht der Hardware prüft
jedoch der Trampolinprüfbefehl
einfach eine Bedingung und unterbricht, falls die Bedingung wahr
ist.
-
Ein
Ausführungsbeispiel
eines Betriebs der Unterbrechungshandhabungsroutine 82 zum
Abschließen
der Semantik der emulierten Verzweigung, die durch den Trampolinmechanismus
ausgeführt wird,
ist allgemein bei 200 in Flussdiagrammform in 3 dargestellt.
Bei Schritt 202 wird der Wert des Befehlszeigers 71 zum
Zeitpunkt der Unterbrechung in ein erstes temporäres Register kopiert.
-
Bei
Schritt 204 wird die Adressverschiebung, die durch den
Trampolinprüfbefehl
geliefert wird, in ein zweites temporäres Register kopiert. Bei einem Ausführungsbeispiel
sind keine speziellen temporären
Register für
den Betrieb der Unterbrechungshandhabungsroutine 200 notwendig,
weil Softwarekonvention spezifizieren kann, dass effektiv zwei normale
temporäre
Register durch den Trampolinprüfbefehl
verwendet werden. Bei einem anderen Ausführungsbeispiel bewirkt eine
Unterbrechung, dass ein Satz von Registern automatisch für die Verwendung durch
die Unterbrechungshandhabungsroutine gespeichert wird.
-
Bei
einem Ausführungsbeispiel
wird Schritt 206 durchgeführt, bei dem der IIM-Adressverschiebungswert,
der in dem zweiten temporären
Register gespeichert ist, um ein Vorzeichen erweitert ist, um negative
Verzweigungsverschiebungen zu ermöglichen. Bei einem Ausführungsbeispiel
ist die Verschiebung in Hardware um ein Vorzeichen erweitert, in
diesem Fall muss Schritt 206 nicht durchgeführt werden.
-
Bei
Schritt 208 werden der erste temporäre Registerwert und der zweite
temporäre
Wert addiert, und die Summe wird in dem ersten temporären Register
gespeichert. Bei einem Ausführungsbeispiel richtet
ein Schiebe- und Addierbefehl die Verschiebung aus, um eine größere Verschiebungsfähigkeit zu
liefern. Bei einem alternativen Ausführungsbeispiel wird eine Verschiebung
ausgerichtet in die IIM-Register 76 geliefert, in diesem
Fall führt
Schritt 208 einfach einen normalen Addierbefehl durch,
um die Summe in dem ersten temporären Register zu platzieren.
-
Bei
Schritt 210 wird die Summe, die bei Schritt 208 in
dem ersten temporären
Register gespeichert wird, in den Befehlszeiger 71 kopiert.
Bei Schritt 212 wird das Programm an dem neuen Adresswert,
der bei Schritt 210 in dem Befehlszeiger 71 gespeichert
wurde, neu gestartet.
-
Der
Trampolinmechanismus gemäß der vorliegenden
Erfindung emuliert effektiv einen Verzweigungsbefehl, wo der Mehraufwand
minimal ist, falls die Bedingung falsch ist. Der Trampolinmechanismus führt keine
Verzweigung durch und daher gibt es keine Möglichkeit einer Verzweigungsfalschvorhersage, was
zu reduzierten Barrieren der Codezeitplanung führt. Außerdem werden durch den Trampolinmechanismus
keine Verzweigungsressourcen verbraucht und daher ist die Leistungsfähigkeit
anderer Verzweigungen nicht verschlechtert.
-
Ferner
muss das Computersystem 50 in der Lage sein, Unterbrechungen
auf den meisten Befehlen zu erfassen, daher fügt der Trampolinunterbrechungsmechanismus
den bestehenden Unterbrechungserfassungs- und Priorisierungsmechanismen des
Computersystems 50 wenig Komplexität hinzu. Der Trampolinprüfbefehl
gemäß der vorliegenden
Erfindung ermöglicht
es dem Computersystem 50, in jedem Zyklus eine große Anzahl
von Tests durchzuführen,
wobei jeder Test eine Steuerflussänderung bewirken kann, ohne
zusätzliche
Hardware, wie es in Mehrwegverzweigung erforderlich wäre.
-
Wenn
die Trampolinprüfbedingung
wahr ist, ist der Mehraufwand, der erforderlich ist, um die Bedingung
handzuhaben, wesentlich geringer als der oben beschriebene Signalhandhabungsroutinelösungsansatz.
Die Unterbrechungshandhabungsroutine 82 zum Implementieren
des Trampolinmechanismus muss nicht unterscheiden zwischen unterschiedlichen
potentiellen Ursachen der Unterbrechung in dem Ausführungsbeispiel,
wo der Unterbrechungsvektor 81 nicht mit anderen Unterbrechungen gemeinschaftlich
verwendet wird. Die Unterbrechungshandhabungsroutine 82 versucht
nicht, eine Auflösung
der Unterbrechungsbedingung selbst durchzuführen. Die Unterbrechungshandhabungsroutine 82 erstellt
keine Datenstrukturen, statt dessen arbeitet der Fehlerhandhabungscode
in dem Prozess selbst einfach an den Daten, wo die Daten gespeichert
sind. Außerdem,
anders als der herkömmliche
Signalhandhabungsroutinelösungsansatz,
muss das Betriebssystem 68 nicht aufgerufen werden, um
die Programmsicherung zu starten, nachdem die Unterbrechungsbedingung
gehandhabt wurde. Statt dessen, wenn der Fehlerhandhabungscode in
dem Programm die Handhabung der Unterbrechungsbedingung fertig stellt,
wird eine Verzweigung einfach durchgeführt, um eine Steuerflussänderung
zurück
zu dem Hauptprogrammsteuerfluss zu bewirken, und die Ausführung fortzusetzen.
-
Der
Trampolinmechanismus ist ziemlich sinnvoll in Situationen, wo die
geprüfte
Bedingung unwahrscheinlich ist, aber nicht so gut wie nie auftritt. Beispielsweise
tritt diese Art von Situation auf bei den Optimierungstechniken,
die derzeit verwendet werden, um effektiv den wahrscheinlichsten
Pfad eines Programms als einzelne Einheit zu behandeln, und die
weniger wahrscheinlichen Pfade im Wesentlichen als Fehlerbedingungen.
Bei dieser Optimierungstechnik wird die Handhabung der weniger wahrscheinlichen
Programmpfade mit dem Trampolinmechanismus durchgeführt, mit
wesentlich weniger Mehraufwand als der Signalhandhabungsroutinelösungsansatz,
wenn die Bedingung wahr ist, aber ohne die Kosten der Leistung für den wahrscheinlichsten
Pfad des Programms, die verursacht werden könnten, falls ein normaler Verzweigungsbefehl
verwendet wird, um einen Steuerfluss zu bewirken.
-
Eine
Implementierung des Trampolinmechanismus ist für die Wiederherstellung von
weitergeleiteten Ausnahmen, bewirkt durch Befehle, die spekulativ
ausgeführt
werden oder im Voraus ausgeführt werden.
Das Verfahren und die Vorrichtung zum Ermöglichen einer Wiederherstellung
von Problemen, die während
der Ausführung
von vorgezogenen oder spekulierten Befehlen auftreten, wird nachfolgend näher beschrieben.
Bezüglich
der Verwendung eines Trampolinmechanismus für die Wiederherstellung von
Ausnahmen, die durch vorgezogene oder spekulative Befehle verschoben
werden, erzeugt der Kompilierer, der in dem Speicher 58 gespeichert
ist, spezielle Befehle, die als spekulative Befehle bezeichnet werden,
die früh
und spekulativ durchgeführt
werden.
-
Die
Arbeit, die durch diese vorgezogenen oder spekulativen Befehle durchgeführt wird,
kann zu Ausnahmebedingungen führen.
Diese Ausnahmebedingungen müssen
keinen unmittelbaren Effekt haben, da an dem Punkt, wenn die Arbeit
der vorgezogenen oder spekulativen Befehle durchgeführt wird, die
Arbeit vorgezogen oder spekulativ durchgeführt wird. Zu dem Zeitpunkt,
zu dem die vorgezogene oder spekulative Arbeit erforderlich ist,
wird ein spezieller Prüfbefehl,
der nachfolgend beschrieben ist, verwendet, um zu erfassen, ob es
irgendwelche Ausnahmebedingungen gibt. Falls es irgendwelche Ausnahmebedingungen
gibt, ruft der Trampolinmechanismus einen speziellen Abschnitt des
Programmcodes auf, der genau zugeschnitten ist, um die vorgezogene
oder spekulativ durchgeführte
Arbeit zu wiederholen. In diesem Fall ist die Arbeit nicht mehr
spekulativ und alle Ausnahmen werden sofort gehandhabt. Wenn die
Arbeit erneut ausgeführt
wird, wird ein Verzweigungsbefehl ausgeführt, um den Steuerfluss zurück zu dem
Hauptprogrammsteuerfluss zu ändern,
und die Ausführung
fortzusetzen.
-
Das
bevorzugte Ausführungsbeispiel
liefert ein Verfahren und eine Vorrichtung zum Wiederherstellen
von Problemen, die während
der Ausführung von
statisch spekulierten Befehlen auftreten. Ein Ausführungsbeispiel
der vorliegenden Erfindung bezieht sich auf das Ausführen jedes
Typs von Befehlssegment, das durch einen Kompilierer geplant wurde,
um spekulativ ausgeführt
zu werden, das Verifizieren der Integrität der Ausführung der Befehle, die spekulativ
ausgeführt
wurden, und das Ausführen von
Wiederherstellungscode zum Korrigieren von Problemen, falls irgendwelche
Probleme erfasst werden.
-
Befehle
sind in zwei Klassen unterteilt: spekulativ und nicht-spekulativ.
Am Beginn der Kompilierung werden alle Befehle initialisiert, um
nicht-spekulativ zu sein. Wenn während
dem Verlauf der Planung der Kompilierer einen Befehl außerhalb
des Ursprungsbasisblocks des Befehls plant, markiert der Kompilierer
den Befehl als spekulativ. Nicht-spekulative Befehle, die auf eine
Ausnahmebedingung treffen, erzeugen eine Ausnahme. Spekulative Befehle, die
auf eine Ausnahmebedingung treffen, erzeugen keine Ausnahme, sondern
schreiben statt dessen ein „verschobenes
Ausnahmetoken" (DET;
DET = deferred execution token) in ihren Bestimmungsort. Die Existenz
der Ausnahmebedingung verhindert, dass ein spezifizierter Rechenbefehl
mit den ordnungsgemäßen Operanden
abgeschlossen wird, und daher umfasst der Bestimmungsort des Befehls
das DET anstatt dem korrekten Ergebnis. Ein nicht-spekulativer Befehl,
der ein DET liest, schreibt ein weiteres DET in den Befehlsbestimmungsort
(es ist erneut anzumerken, dass der Bestimmungsort nicht das korrekte
Ergebnis enthält) – dieses
Verhalten wird als „Ausbreitung" bezeichnet. Durch
Platzieren eines nicht-spekulativen Befehls in den Ursprungsbasisblock
eines bestimmten spekulativen Befehls, und durch Konfigurieren des
nicht-spekulativen Befehls zum Lesen eines Bestimmungsorts des spekulativen Befehls
(oder jede Stelle, in die ein DET ausgebreitet werden kann), kann
ein DET, das durch den spekulativen Befehl erzeugt wird, an dem
Punkt erfasst werden, an dem die Steuerung zu dem Ursprungsbasisblock übertragen
wird. An diesem Punkt ist es notwendig, die Ausnahmebedingung, die
die ursprüngliche
Erzeugung des DET bewirkt hat, neu zu erzeugen, und alle vorher
ausgebreiteten DETs mit den korrekten Ergebnissen zu ersetzen. Dies
wird durch einen Prozess erreicht, der als „Wiederherstellung" bezeichnet wird.
Wiederherstellung kann das Vergrößern des
Programms mit zusätzlichem
Code umfassen, der durch den Kompilierer erzeugt wird; der Code
ist eine Kopie eines Satzes von abhängigen spekulativen Befehlen
in nicht-spekulativer
Form, so dass auf die Ausführung
hin alle Ausnahmebedingungen Ausnahmen erzeugen und alle vorher
geschriebenen Bestimmungsorte mit den korrekten Ergebnissen überschrieben
werden. Der Wiederherstellungscode muss keine exakte Kopie der Befehlssequenz
sein, sondern kann ein Code sein, der, wenn er ausgeführt wird,
das gleiche Ergebnis erzielt. Ferner ist bei einem Ausführungsbeispiel
der Erfindung ein neuer Befehl definiert mit dem spezifischen Zweck
des Prüfens
der Existenz von DETs, und des Aktivierens des zugeordneten Wiederherstellungscodes
in dem Fall, dass ein DET erfasst wird.
-
Das
oben erörterte
Ausführungsbeispiel
der vorliegenden Erfindung hängt
nicht von der genauen Form des DET ab. Außerdem sind alternative Ausführungsbeispiele
zum Spezifizieren spekulativer und nicht-spekulativer Befehle möglich, ohne
den Schutzbereich der vorliegenden Erfindung zu beeinträchtigen.
Beispielsweise können
einige Befehle definiert sein, um sich spekulativ zu verhalten,
unabhängig
davon, ob die Befehle außerhalb
des Ursprungsbasisblocks geplant waren.
-
Die
Spekulation, auf die bis zu diesem Punkt Bezug genommen wurde, wird
als „Steuerspekulation" bezeichnet, da Befehle
ausgeführt
werden, bevor die Steuerung zu denselben geleitet wird. Spekulation
kann neben der Steuerspekulation andere Formen annehmen. Ein Beispiel
dafür ist „Datenspekulation", wobei ein Mechanismus
definiert ist, der es ermög licht,
dass der Befehl A, der von dem Befehl B abhängig sein kann, vor dem Befehl
B ausgeführt wird.
Obwohl Datenspekulation sich auf jede Klasse von Befehlen beziehen
kann, werden nachfolgend Ladebefehle und Speicherbefehle erörtert, um
Datenspekulation zu demonstrieren. Ein Ladebefehl, der unter einem
Speicherbefehl ist, kann im Allgemeinen nicht über dem Speicherbefehl geplant
werden, es sei denn, es kann gezeigt werden, dass die Adresse, die
durch den Ladebefehl gelesen wird, nie gleich ist wie die Adresse,
die durch den Speicherbefehl geschrieben wird. Falls die Adressen
gleich sind, dann sollte der Ladebefehl die Ergebnisse des Speicherbefehls
erzielen. Falls jedoch gezeigt werden kann, dass die Adresse, die
durch den Ladebefehl gelesen wird, nie gleich ist wie die Adresse,
die durch den Speicherbefehl geschrieben wird, dann kann der Ladebefehl
sicher über
dem Speicherbefehl geplant werden. Datenspekulation tritt auf, wenn
der Kompilierer den Ladebefehl über
dem Speicherbefehl plant, wenn es nicht bewiesen werden kann, dass
die Adressen, auf die durch beide zugegriffen wird, nie gleich sein
werden. Wenn die Adressen, auf die durch beide Befehle zugegriffen
wird, zur Laufzeit als gleich bestimmt werden, tritt eine Fehlerbedingung, die
als Kollision bekannt ist, auf. Im Fall einer Kollision kann ein
Wiederherstellungsmechanismus verwendet werden, um alle falsch geschriebenen
Bestimmungsorte zu korrigieren. Bei einem Ausführungsbeispiel der vorliegenden
Erfindung sind ein Ladebefehl und ein oder mehrere Befehle, die
von denselben abhängen,
durch den Kompilierer über
einem Speicherbefehl geplant, selbst wenn der Kompilierer bestimmt,
dass es eine Kollision zwischen den beiden Befehlen geben kann.
Somit beziehen sich Aspekte der vorliegenden Erfindung auf Steuerspekulation,
Datenspekulation, sowie andere Formen von Spekulation.
-
Ein
Aspekt der vorliegenden Erfindung liefert eine Technik, bei der
ein Kompilierer Befehle planen kann, die spekulativ auszuführen sind,
dennoch kann sich das Computersystem von Spekulationsfehlern erholen,
die während
der spekulativen Ausführung der
Befehle auftreten. Ein weiterer Aspekt der vorliegenden Erfindung
bezieht sich auf ein Verfahren und eine Vorrichtung, zum Vorziehen
eines Befehls außer der
Reihe. Dies umfasst das Planen eines zweiten Befehls, sowie eine
gesamte Berechnung, die davon abhängt (z. B. ein Ladebefehl),
der vor einem ersten Befehl (z. B. einem Speicherbefehl) auszuführen ist, der
eine Fehlerbedingung erzeugen kann, die als Kollision bekannt ist,
aufgrund dessen, dass der erste und der zweite Befehl auf die gleiche
Adresse in einem Teil eines Speichers zugreifen.
-
Um
einige Aspekte der vorliegenden Erfindung zu implementieren, kann
eine Computerarchitektur definiert werden, die es einem Kompilierer
ermöglicht,
Befehle außerhalb
ihres Ursprungsbasisblocks (Steuerspekulation) zu planen, und eine
parallele Ausführung
von Befehlen zu planen, die potentiell auf die gleiche Speicherstelle
zugreifen können (Datenspekulation),
und daher potentiell abhängig sind.
Ein Beispiel einer solchen Computerarchitektur ist näher beschrieben
in Ross u. a., U.S.-Patent Nr. 5,915,117 mit dem Titel „COMPUTER
ARCHITECTURE FOR THE DEFERRAL OF EXCEPTIONS ON SPECULATIVE INSTRUCTIONS", das hierin durch Bezugnahme
aufgenommen ist. Obwohl die Ausführungsbeispiele
nachfolgend mit Bezugnahme auf diese Architektur beschrieben sind,
ist die vorliegende Erfindung nicht auf die Verwendung mit dieser
Architektur beschränkt,
und kann unter Verwendung anderer Architekturmerkmale realisiert
werden, wie es nachfolgend näher
beschrieben ist.
-
Diese
neue Architektur definiert einen Satz von „spekulativen" Befehlen, die nicht
unmittelbar eine Ausnahme signalisieren, wenn eine Ausnahmebedingung
auftritt. Statt dessen verschoben ein spekulativer Befehl eine Ausnahme
durch Schreiben eines „verschobenen
Ausnahmetoken" (DET)
in den Bestimmungsort, der durch den Befehl spezifiziert wird. Der
Befehlssatz enthält
auch „nicht-spekulative" Befehle, die unmittelbar
eine Ausnahme signalisieren, wenn eine Ausnah mebedingung auftritt,
wie es für
herkömmliche
Befehle üblich
ist.
-
Befehlsausnahmen
sind in der Technik gut bekannt und umfassen, sind aber nicht beschränkt auf,
Ausnahmen, wie z. B. Seitenfehler, illegale Operanden, Privilegverletzungen,
Teilen-Durch-Null-Operationen, Überläufe und
dergleichen. Die neue Architektur liefert auch einen neuen Typ von
Speicherspekulation, wobei ein Ladebefehl, der einem Speicherbefehl
in der logischen Reihenfolge folgt, die durch einen Programmierer
definiert wird, vor dem Speicherbefehl ausgeführt werden kann, auf der Basis
der Spekulation, dass die beiden Fälle nicht auf die gleiche Speicherstelle
zugreifen. Eine Speicherspekulationsprüfung, die beispielsweise eine
vorgezogene Ladeadresstabelle (ALAT) zugreifen kann, die eine Aufzeichnung
von jüngsten spekulativen
Speicherzugriffen enthält,
kann geliefert werden, um zu bestimmen, ob die Spekulation richtig ist.
Falls die Spekulation richtig ist, wurden die Befehle ordnungsgemäß ausgeführt. Falls
nicht, werden der Ladebefehl und alle Befehle, die von dem Ladebefehl
abhängen
und vor dem Speicherbefehl geplant waren, erneut ausgeführt, um
die Inhalte wiederzugewinnen, die durch den Speicherbefehl geschrieben
wurden.
-
Unter
Verwendung von Befehlen, die als spekulativ markiert werden, kann
ein Kompilierer Befehle außerhalb
ihres Ursprungsbasisblocks planen, und kann möglicherweise abhängige Speicherzugriffe
parallel planen. Wie es oben angemerkt wurde, wenn ein spekulativer
Befehl eine Ausnahme erzeugt, kann ein „verschobener Ausnahmetoken" in den Bestimmungsort
geschrieben werden, der durch den Befehl spezifiziert wird. Jeder
spekulative Befehl, der ein DET in einer Quelle erfasst, kopiert
das DET in seinen Bestimmungsort. Es ist anzumerken, wenn ein spekulativer
Befehl ein DET in einer Quelle findet, derselbe nicht die Funktion
im Zusammenhang mit dem Befehl ausführen muss. Der Befehl kann
einfach das DET in den Bestimmungsort kopieren. Auf diese Weise
breitet sich das DET durch den Block von spekulativen Befehlen aus.
-
Somit
kann bei einem Ausführungsbeispiel der
Erfindung ein Bestimmungsort, der das Ergebnis einer Berechnung
umfassen würde,
auf eine DET geprüft
werden, ohne jeden Operanden zu prüfen, der bei der Berechnung
verwendet wird.
-
Jeder
nicht-spekulative Befehl, der ein DET in einer Quelle erfasst, kann
eine unmittelbare Ausnahme erzeugen. Folglich breiten sich DETs
durch spekulative Befehle in einer Datenflussweise aus, bis (und
falls) dieselben einen nicht-spekulativen
Befehl erreichen.
-
Falls
ein Programm bei der Laufzeit bestimmt, dass die Spekulation, auf
der Befehle ausgeführt
wurden, falsch war (beispielsweise eine Verzweigung, die falsch
vorhergesagt wurde) kann das Programm die DETs einfach ignorieren,
da das Programm nicht auf die DETs zugreift. Falls die Spekulation
jedoch korrekt war, werden die DETs in eine tatsächliche Ausnahme umgewandelt,
falls und wenn der Ursprungsbasisblock des Befehls, der das DET erzeugt
hat, ausgeführt
wird. Bei einem Ausführungsbeispiel
wird diese Umwandlung durch einen Befehl durchgeführt, der
der „Spekulationsprüfungs"-Befehl genannt wird,
oder kurz „chk.s". Der chk.s-Befehl liest eine
Quelle, und falls die Quelle ein DET enthält, verzweigt er zu einer bestimmten
Zieladresse, die einen Wiederherstellungscode implementiert. Gleichartig
dazu kann bei einem Ausführungsbeispiel
der vorliegenden Erfindung die Korrektheit der Speicherspekulation
bestimmt werden durch einen „Vorausprüf"-Befehl, der als
chk.a-Befehl bezeichnet
wird. Der chk.a-Befehl bestimmt, ob auf eine Speicherstelle außer der
Reihenfolge zugegriffen wurde, und falls dies der Fall ist, verzweigt
der chk.a-Befehl
zu einer bestimmten Zieladresse, die Wiederherstellungscode implementiert.
Der chk.a-Befehl wird nachfolgend näher erörtert. Chk.s und chk.a können jeweils auf
eine Anzahl von Möglichkeiten
implementiert werden, die zu einer Änderung des Steuerflusses der Befehle
führen,
die ausgeführt
werden. Beispielsweise kann jeder als ein bedingter Verzweigungsbefehl implementiert
werden. Bei einem Ausfüh rungsbeispiel
können
der chk.s-Befehl und/oder der chk.a-Befehl als ein Befehl implementiert
werden, wie z. B. der oben beschriebene Trampolinprüfbefehl,
der eine Ausnahme erzeugt, die eine Ausnahmehandhabungsroutine aufruft,
wie z. B. die Unterbrechungshandhabungsroutine 82, um eine
Steuerflussänderung
mit einem Trampolinmechanismus gemäß der vorliegenden Erfindung
zu bewirken, wie es in den Flussdiagrammen von 2 und 3 dargestellt ist
und oben beschrieben ist.
-
Durch
Definition sind die chk.s- und chk.a-Befehle immer nicht-spekulativ.
Allgemein, falls diese Befehle ein DET oder eine falsche Speicherspekulation
erfassen, wird Wiederherstellungscode ausgeführt, der nicht-spekulative
Versionen der verletzenden Befehle umfasst. Mit Bezugnahme auf einen
chk.s-Befehl, der ein DET erfasst, wird auf die Ausführung des
Wiederherstellungscodes hin die nicht-spekulative Version des verletzenden
Befehls das DET in seinem Bestimmungsort mit dem korrekten Ergebnis
ersetzen, und/oder die Ausnahme erzeugen. Falls irgendwelche späteren spekulativen Befehle
von dem verletzenden Befehl abhängen, sind
dieselben ebenfalls in dem Wiederherstellungscode enthalten, um
wieder ausgeführt
zu werden, weil die DETs in die späteren Bestimmungsorte der spekulativen
Befehle ausgebreitet wurden, und daher können diese Bestimmungsorte
falsche Ergebnisse enthalten. Bezüglich eines chk.a-Befehls muss der
Wiederherstellungscode den verletzenden Ladebefehl erneut ausführen, um
den richtigen Inhalt von dem Speicher zu laden. Außerdem werden
alle Befehle, die von dem verletzenden Ladebefehl abhängen, die über dem
Speicherbefehl geplant wurden, von dem der Ladebefehl abhängt, ebenfalls
neu ausgeführt.
Das Planen der Ladebefehle und die Berechnungsbefehle, die von dem
geladenen Wert über dem
Speicherbefehl abhängen,
werden nachfolgend näher
erörtert.
Alle Befehle, die nicht von dem verletzenden Befehl abhängen, werden
nicht wieder ausgeführt,
da dies nicht notwendig ist, und da einige derselben den Programmzustand
falsch modifizieren würden,
falls dieselben wieder ausgeführt würden. Da
der Kompilierer die spekulativen Befehle und die spekulativen Prüfungen geplant
hat, ist der Kompilierer in der Lage, Wiederherstellungscode zu
erzeugen, der für
einen bestimmten Satz von spekulativen Befehlen geeignet ist.
-
Die
Ausführungsbeispiele
können
realisiert werden durch ein Computersystem mit einem Kompilierer,
der in der Lage ist, Befehle für
eine spekulative Ausführung
zu planen und entsprechenden Wiederherstellungscode zu erzeugen,
und eine Architektur, die in der Lage ist, Befehle auszuführen, die
als spekulativ markiert sind, wie z. B. ein Computersystem, das
die oben beschriebene Architektur implementiert.
-
4 zeigt
eine Ursprungscodesequenz 10, die aus drei Grundblöcken A1,
B1 und C1 besteht. Die Ursprungscodesequenz 10 stellt Code
dar, wie er durch einen Programmierer spezifiziert wird. In dem Code 10 stellt
der Befehl I0 Befehle dar, die vor dem Befehl I2 kommen. Der Befehl
I2 ist ein Verzweigungsbefehl, der zu dem Befehl I14 verzweigt,
falls die Inhalte des Registers r0 Nicht-Null sind. Der Befehl I4
lädt das
Register r1 mit den Inhalten der Speicherstelle, auf die das Register
r2 zeigt. Der Befehl 16 verschiebt Inhalte des Registers r1 nach
links um drei Positionen und schreibt das Ergebnis in das Register
r3. Der Befehl I8 addiert die Inhalte des Registers r3 und r5 und
schreibt das Ergebnis in das Register r4. Der Befehl I10 vergleicht
die Inhalte des Registers r4 mit den Inhalten des Registers r7.
Falls die Inhalte des Registers r4 größer sind als die Inhalte des
Registers r7, dann wird. ein Nicht-Nullwert in das Register r6 geschrieben.
Andernfalls wird Null in das Register r6 geschrieben. Der Befehl
I12 ist ein Verzweigungsbefehl, der zu dem Befehl I100 verzweigt (in 4 nicht
gezeigt), falls die Inhalte des Registers r6 Nicht-Null sind. Schließlich stellt
der Befehl I14 Befehle dar, die nach dem Befehl I12 kommen, wenn die
Verzweigung nicht ausgeführt
wird. In dem Basisblock B1 hängt
der Befehl I12 von dem Befehl I10 ab, der wiederum von dem Befehl
I8 abhängt,
der wiederum von dem Befehl I6 abhängt, der wiederum von dem Befehl
I4 abhängt.
-
5 zeigt
eine geplante Codesequenz 20, die sich aus dem Planen des
Ursprungscodes 10 von 4 ergibt,
unter Verwendung von statischer Spekulation gemäß einem darstellenden Ausführungsbeispiel
der vorliegenden Erfindung. In 5 wurden die
Befehle I4, I6 und I8 außerhalb
ihres Ursprungsbasisblocks B1, und in dem Block A1 geplant, und wurden
daher als spekulativ markiert durch den Kompilierer (angezeigt durch
den „.s"-Modifizierer). Die Befehle
I10 und I12 wurden nicht außerhalb
ihres Ursprungsbasisblocks B1 geplant, und sind nicht mit einem „.s" markiert, da dieselben
nicht-spekulativ sind.
-
Bei
einem Ausführungsbeispiel
der vorliegenden Erfindung verhalten sich bestimmte Befehle, insbesondere
diejenigen, die keine Ausnahmen bewirken, immer, als ob sie spekulativ
wären (und
beispielsweise DETs ausbreiten), unabhängig davon, ob dieselben außerhalb
ihres Ursprungsbasisblocks geplant wurden. Daher sind diese Befehle
nicht explizit als spekulativ oder nicht-spekulativ markiert. Bestimmte
andere Befehle, die Ausnahmen bewirken, wie z. B. Ladebefehle, können sowohl
spekulative als auch nicht-spekulative Arten haben. Daher markiert der
Kompilierer diese explizit als spekulativ oder nicht-spekulativ,
abhängig
davon, wie dieselben geplant werden. Dies gilt ebenso für alternative
Ausführungsbeispiele,
wie z. B. diejenigen, wo jeder Befehl explizit und individuell als
spekulativ oder nicht-spekulativ
markiert ist.
-
Eine
Sequenz von abhängigen
spekulativen Befehlen, beginnend mit dem frühesten spekulativen Befehl
und endend mit dem letzten spekulativen Befehl, alle von dem gleichen
Basisblock, wird als eine „spekulative
Abhängigkeitskette" bezeichnet (wie
sie hierin verwendet werden, sind „früh" und „spät" durch die ursprüngliche Programmreihenfolge
definiert). In dem in 4 und 5 gezeigten
Code beginnt die spekulative Abhängigkeitskette
mit dem Befehl I4, umfasst den Befehl I6 und endet mit dem Befehl
I8. Falls ein Befehl in der spekulativen Abhängigkeitskette auf eine Ausnahmebedingung
trifft, dann wird ein DET an den Bestimmungsort des verletzenden Befehls
geschrieben und verbreitet sich nach unten entlang der spekulativen
Abhängigkeitskette.
Falls beispielsweise der Befehl I4 auf eine Ausnahmebedingung trifft,
wie z. B. einen Seitenfehler, wird ein DET in das Register r1 geschrieben.
Der Befehl I6 wird wiederum auf das Lesen eines DET von dem Register
r1 hin, ein DET in das Register r3 schreiben. Gleichartig dazu wird
der Befehl I8, auf das Lesen eines DET in dem Register r3 hin, wiederum
ein DET in das Register r4 schreiben. Es ist anzumerken, dass bei
diesem Beispiel der Befehl I6 keine Schiebefunktion durchführen muss,
die durch den shl.s-Befehl
spezifiziert ist, und der Befehl I8 nicht die Addierfunktion durchführen muss,
die durch die add.s-Operation
spezifiziert ist. Dieser Befehl kann einfach das verschobene Ausführungstoken
ausbreiten. Sobald ein verschobenes Ausführungstoken erzeugt ist, können folglich
Ausführungsressourcen, die
andernfalls durch die Ausführung
der spekulativen Befehle verbraucht würden, verfügbar gemacht werden, um andere
Befehle auszuführen,
oder können
ruhend verbleiben, und somit den Leistungsverbrauch reduzieren.
-
Bei
dem Befehl I2 wird das Register r0 bewertet. Falls das Register
r0 Nicht-Null ist, verzweigt die Ausführung zu dem Befehl I14, in
diesem Fall ist der Wert, der in dem Register r4 gespeichert ist,
nicht erforderlich, da die Befehle I4, I6 und I8 auf der Basis einer
falschen Spekulation ausgeführt
wurden, und jede Ausnahme, die durch die Befehle I4, I6 oder I8 erzeugt
wird, kann ignoriert werden. Da der Kompilierer weiß, dass
die Befehle I14 und die Befehle, die folgen, nur ausgeführt werden,
falls die Befehle I4, I6 und I8 nicht ausgeführt werden sollen, können die Befehle
I14 und die folgenden Befehle einfach die Ergebnisse ignorieren,
die in die Register r1, r3 und r4 platziert wurden, und diese Register
für andere
Zwecke wiederverwenden. Es liegt in der Verantwortung des Kompilierers,
Code zu erzeugen, um die Effekte der Befehle ordnungsgemäß zu adressieren,
die aufgrund einer falschen Spekulation spekulativ ausgeführt wurden.
-
Falls
das Register r0 Null ist, dann werden die Ergebnisse der Befehle
I4, I6 und I8 jedoch validiert. Während der Planung durch den
Kompilierer wird zu dem Zeitpunkt, zu dem der erste Befehl von einem
bestimmten Basisblock spekulativ gemacht wird (bei diesem Beispiel
Befehl I4), ein chk.s-Befehl (Befehl
I9 in 5) durch den Kompilierer emittiert und in diesen
Basisblock platziert (bei diesem Beispiel B1). Wie es oben angemerkt
wurde, ist der chk.s nicht-spekulativ, und ist nicht außerhalb
des Basisblocks geplant, in den derselbe platziert wurde. Der chk.s
beim Befehl I9 liest das Register r4, das das Bestimmungsregister
des Befehls I8 ist. Der Befehl I9 verifiziert die Ergebnisse aller
Befehle in der obigen spekulativen Abhängigkeitskette, einschließlich der
Befehle, deren Bestimmungsort durch den Befehl 19 gelesen wird,
was die Befehle I4, I6 und I8 sind.
-
Falls
ein DET nicht durch die Ausführung
der Befehle I4, I6 und I8 erzeugt wurde, dann wurden die Befehle
I4, I6 und I8 validiert, wodurch bestätigt wird, dass die spekulative
Ausführung
dieser Befehle erfolgreich war. Folglich fährt die Ausführung mit
dem Befehl I10 fort.
-
Falls
die Befehle I4, I6 oder I8 ein DET erzeugten, dann wird dieses DET
zu dem Register r4 ausgebreitet, wo der Befehl I9 das DET erfassen wird.
Befehle in der spekulativen Abhängigkeitskette (Befehle
I4, I6 und I8) haben unzuverlässige
Ergebnisse erzeugt, weil ihre Bestimmungsregister DETs statt korrekten
Ergebnissen enthalten. Folglich erfasst der chk.s.-Befehl (I9) das
DET und verzweigt zu Wiederherstellungscode, der an dem Befehl I4r
beginnt. Die Befehle I4r, I6r und I8r sind nicht-spekulative Versionen der
Befehle I4, I6 bzw. I8, und der Befehl I9r verzweigt zu dem Befehl
I9, um den chk.s-Befehl wiederauszuführen. Obwohl es nicht immer
notwendig sein muss, den Befehl I9 wiederauszuführen, gibt es viele Situationen,
wo es gute Praxis ist, dies zu tun, wie z. B. wenn spekulative Abhängigkeitsketten
voneinander abhängen.
-
Da
die Befehle I4r, I6r und I8r nicht-spekulativ sind, werden sie keine
Ausnahmen verschieben. Daher werden Ausnahmen erzeugt und verarbeitet. Man
nehme beispielsweise an, dass der Befehl I4r einen Seitenfehler
erzeugt. Die Steuerung wird zu der Ausnahmehandhabungsroutine übertragen,
die für das
Adressieren von Seitenfehlern verantwortlich ist, und der Fehler
wird verarbeitet. Die Programmausführung kann beispielsweise angehalten
werden, oder eine Speicherseite kann von einer virtuellen Speicheraustauschdatei
eingelesen werden.
-
Wie
es oben angemerkt wurde, um den korrekten Programmzustand beizubehalten,
wird es nur Befehlen von der verletzenden spekulativen Abhängigkeitskette
erlaubt, den Prozessorzustand während der
Ausführung
des Wiederherstellungscodes zu modifizieren. Bei dem in 5 gezeigten
Beispiel werden nur die Befehle I4, I6 und I8 wieder ausgeführt, als
die Befehle I4r, I6r und I8r, und die anderen Befehle nicht. Diese
selektive Wiederausführung
wird erreicht durch Herstellen einer Kopie aller Befehle in der
spekulativen Abhängigkeitskette
beginnend mit dem frühesten
Befehl und endend mit dem Befehl, dessen Bestimmungsort durch den
chk.s-Befehl gelesen wird. Diese Kopie wird als der „Wiederherstellungscode" bezeichnet, und
der chk.s-Befehl überträgt die Steuerung
zu dem Wiederherstellungscode in dem Fall, dass der chk.s-Befehl
auf ein DET trifft. Am Ende des Wiederherstellungscodes emittiert
der Kompilierer eine Verzweigung zurück zu dem Befehl I9. Da der
Wiederherstellungscode nur ausgeführt wird, falls der entsprechende
chk.s-Befehl ausgeführt wird,
und da chk.s immer nicht-spekulativ
ist, sind alle Befehle in dem Wiederherstel lungscode nicht-spekulativ.
Somit werden die Befehle in dem Wiederherstellungscode in nicht-spekulative
Versionen umgewandelt (falls notwendig). Bei dem in 5 gezeigten Beispiel
sind die Hauptleitungsversionen der Befehle I4, I6 und I8 alle als
spekulativ markiert, während
die Wiederherstellungscodekopien (Befehle I4r, I6r und I8r) alle
als nicht-spekulativ markiert sind. Der gleiche Wiederherstellungscode
kann durch mehrere chk.s-Befehle angesteuert werden. Ferner kann
die gleiche spekulative Abhängigkeitskette
mehrere zugeordnete Wiederherstellungscodes haben, indem dieselbe
getrennte chk.s-Befehlsverzweigungen zu getrennten Wiederherstellungscodesegmenten
hat.
-
Die
Existenz eines DET zeigt an, dass eine Ausnahmebedingung aufgetreten
ist, auf einem Befehl in einer spekulativen Abhängigkeitskette. Bevor daher
irgendwelche Befehle wieder ausgeführt werden, wird die Ausnahmebedingung
zunächst
gehandhabt durch Aktivieren der zugeordneten Ausnahmehandhabungsroutine.
Ein Ausführungsbeispiel
der vorliegenden Erfindung erfüllt
diese Erforderung automatisch, weil der Wiederherstellungscode nicht-spekulative
Kopien aller relevanter Befehle in der spekulativen Abhängigkeitskette
enthält,
und nicht-spekulative Befehle sofort Signalausnahmen signalisieren.
Auf die Ausführung
des Wiederherstellungscodes hin wird die ursprüngliche Ausnahme durch den
verletzenden Befehl und wieder erzeugt die entsprechende Ausnahmehandhabungsroutine wird
aktiviert. Nachdem die Ausnahmehandhabungsroutine die Ausnahmebedingung
korrigiert, wird die Steuerung zu dem Wiederherstellungscode zurückgeleitet,
der das Ausführen
des Rests des Befehls fortführt,
bevor er zu dem Hauptleitungscode zurückkehrt.
-
Das
System hängt
nicht von einem bestimmten DET-Format ab. Bei dem bevorzugten Ausführungsbeispiel
zeigt das DET einfach an, dass eine verschobene Ausnahme existiert
und enthält
keine weiteren Informationen. Alternative Ausführungsbeispiele können das
DET definieren, um andere Informationen zu enthalten, die von einer
bestimmten Ausnahme handhabungsroutine benötigt werden, z. B. den Ausführungstyp,
die Adresse des verletzenden Befehls usw.
-
Andere
Ausführungsbeispiele
liefern auch die Wiederherstellung von anderen Spekulationstypen,
wie z. B. Datenspekulation. Bei einem Ausführungsbeispiel der vorliegenden
Erfindung werden Ladebefehle, die außer der Reihe vor den Speicherbefehlen
vorgezogen werden, verwendet, um Datenspekulation darzustellen und
werden mit Bezugnahme auf 6–8 beschrieben.
Wie sie hierin verwendet werden, zeigen die Bezugnahmen auf Lade- bzw.
Speicherbefehle alle Befehle, die Lese- und Schreibvorgänge in den
Speicher durchführen,
unabhängig
davon, ob die Befehle andere Funktionen durchführen. Ladebefehle erfordern
typischerweise eine längere
Zeitdauer zum Ausführen
als andere Befehle, aufgrund der Speicherlatenzzeit. Durch Bewegen
eines Ladebefehls früher
in die Ausführung
eines Programms ist die Effizienz von ausführenden Befehlen in einem Computer
verbessert. Der Ladebefehl, der als ein vorgezogener Ladebefehl
bezeichnet wird, ermöglicht
einen Anstieg bei der Parallelität von
Aktivitäten,
die durchgeführt
werden, die Verwendung des Speichers erfordern.
-
Wie
es oben kurz erörtert
wurde, kann ein Kompilierer häufig
nicht mit 100% Sicherheit erfassen, ob ein Ladebefehl und ein Speicherbefehl
kollidieren (d. h. auf eine gemeinsame Speicherstelle zugreifen).
Dies stellt eine Barriere zum Erreichen von Parallelität dar, da
es einen konservativeren Befehlszeitplan erzwingt, der die Ladelatenzzeit
nicht überlappen
wird, d. h. keinen Ladebefehl vor einen Speicherbefehl bewegt, mit
dem derselbe kollidieren könnte.
Bei einem großen
Prozentsatz dieser Fälle kollidieren
die Lade- und Speicherbefehle jedoch nicht. Somit ermöglicht es
ein Ausführungsbeispiel der
vorliegenden Erfindung, dass ein Ladebefehl und davon abhängige Berechnungen
vor einem potentiell kollidierenden Speicherbefehl ausgeführt werden,
als eine Einrichtung zum Verbessern der Parallelität der Programmausführung in
einem Einzel- oder Mehrprozessorsystem.
-
Man
betrachte den einfachen Ursprungscode 30, der in 6 gezeigt
ist. Der Code 30 umfasst: Befehl I22, der die Inhalte des
Registers r3 in eine Speicherstelle speichert, die durch die Inhalte des
Registers r1 indexiert ist; den Befehl I24, der das Register r4
mit den Inhalten der Speicherstelle lädt, die durch die Inhalte des
Registers r2 indexiert ist; und der Befehl I26, der die Register
r4 und r6 addiert und das Ergebnis in das Register r5 schreibt.
Wenn der Kompilierer den Code 30 plant, nimmt man an, dass
derselbe bestimmt, dass es unwahrscheinlich, aber nicht unmöglich ist,
dass die Inhalte des Registers r1 die gleichen sind wie die Inhalte
des Registers r2, wenn die Befehle I22 und I24 ausgeführt werden. Man
nehme ferner an, dass der Kompilierer bestimmt, dass es effizienter
wäre, die
Befehle I24 und I26 vor (oder parallel mit) dem Befehl I22 zu planen. Mit
Bezugnahme auf das parallele Planen der Befehle sollte klar sein,
dass selbst in einem Einzelprozessorsystem der Einzelprozessor typischerweise
mehrere Ausführungseinheiten
umfasst, auf denen mehrere Befehle parallel ausgeführt werden
können.
-
7 zeigt
den geplanten Code 40, der erzeugt wurde, wenn der Kompilierer
den Ursprungscode 30 von 6 geplant
hat, gemäß einem
Ausführungsbeispiel
der vorliegenden Erfindung. Der Code 40 umfasst Befehle
I24 und I26, die vor dem Befehl I22 (dem Speicherbefehl) geplant
wurden. Es wird angemerkt, dass „.a" (was einen vorgezogenen Befehl anzeigt)
an den Ladebefehl angehängt
wurde, was anzeigt, dass dieser Ladebefehl die Ladeadresse in der
vorgezogenen Ladeadresstabelle (ALAT) aufzeichnet. Der Befehl I25
ist ein chk.a-Befehl, der die ALAT prüft, um zu bestimmen, ob der
Lade- (I24) und Speicher- (I22) Befehl auf die gleiche Speicherstelle
zugegriffen haben. Falls die Inhalte des Registers r1 und r2 nicht
gleich waren, haben die Befehle nicht auf die gleiche Speicherstelle
zugegriffen, und chk.a (I25) führt
keine Aktion durch. Falls jedoch die Inhalte des Registers r1 und
r2 gleich waren, erfasst der chk.a-Befehl (I25) einen Datenspekulationsfehler und
verzweigt zu dem Wiederherstellungscode, beginnend bei dem Befehl
I24r. Der Befehl I24r führt den
Ladebefehl neu aus, und bewirkt, dass die richtigen Ergebnisse in
das Register r4 geladen werden, da der Ladebefehl nach dem Speicherbefehl
(I22) neu ausgeführt
wird. Der Befehl I26r führt
den Addierbefehl neu aus, der das korrekte Ergebnis in das Register
r5 schreibt, und der Befehl I23r verzweigt zurück zu dem Befehl I25, was verifiziert,
dass es keinen Datenspekulationsfehler gibt.
-
8 ist
ein Flussdiagramm, das eine beispielhafte Routine darstellt, die
durch einen Kompilierer implementiert werden kann, um die geplanten
Codeänderungen
zu erzeugen, die in 5 und 7 gezeigt
sind. Dieses Flussdiagramm wird lediglich als ein Beispiel geliefert,
da andere Implementierungen möglich
sind. Das System ist nicht begrenzt auf die Verwendung mit einer
spezifischen Programmsprache oder Computerkonfiguration und kann
an einen Kompilierer angewendet werden, der in einem Einzel- oder
Mehrprozessorsystem verwendet wird.
-
Der
Prozess von 8 beginnt bei Schritt 503,
wenn der Kompilierer ein herkömmliches
Abhängigkeitsdiagramm
erzeugt, das Befehle in einem Sourcecomputerprogramm darstellt,
das noch nicht durch den Kompilierer geplant wurde. Die vorliegende
Erfindung ist nicht auf einen bestimmten Diagrammtyp beschränkt. Das
Abhängigkeitsdiagramm kann
mehrere Formen annehmen, einschließlich einem Diagramm mit zumindest
einem Pfad, der ein Segment des Quellcomputerprogramms darstellt, und
einem Knoten, der jeden Befehl in dem Segment des Computerprogramms
darstellt. Das Abhängigkeitsdiagramm
für jedes
Programm umfasst typischerweise eine Mehrzahl von Pfaden, jeder
mit einer Mehrzahl von Knoten. Ein Knoten, der einen Befehl darstellt,
kann mit Informationen versehen werden, die sich auf den Befehl
beziehen, wie z. B. die Anzahl von Taktzyklen, die benötigt werden,
um den Befehl auszuführen.
Typischerweise zeigen Bögen, die
Knoten in dem Diagramm verbinden, eine Abhängigkeit zwischen Befehlen
an.
-
Bei
Schritt 506 überprüft der Kompilierer
das Diagramm und bestimmt, welcher Pfad des Diagramms eine Sequenz
von Befehlen umfasst, die zu einer längsten Gesamtausführungszeit
von Anfang bis Ende führt.
-
Bei
Schritt 509 versucht der Kompilierer, die Ausführung des
längsten
Pfads in dem Programm zu optimieren, da der längste Pfad den kritischen Abschnitt
in dem Programm darstellt, der die Laufzeit der Befehlssequenz begrenzt.
Herkömmliche
Optimierungstechniken können
durch den Kompilierer verwendet werden, und weitere Optimierungstechniken
werden nachfolgend beschrieben, da sich dieselben auf einen vorgezogene
Ladebefehl und seine abhängigen
Berechnungen beziehen.
-
Wie
es oben erwähnt
wurde, ist eine Möglichkeit,
wie der Kompilierer den längsten
kritischen Pfad optimieren kann, durch Datenspekulation. Bei einem
Ausführungsbeispiel
der vorliegenden Erfindung kann dies das Bewegen eines Befehls,
wie z. B. eines Ladebefehls, der eine Leseoperation umfasst, früher in die
Ausführung
des Programms, vor einen Speicherbefehl umfassen, der eine Schreiboperation umfasst.
Bei Schritt 512 bestimmt der Kompilierer, ob ein Ladebefehl
in dem längsten
kritischen Pfad ist. Falls in dem längsten Pfad ein Ladebefehl
enthalten ist, kann der Kompilierer den Ladebefehl und Befehle,
die von demselben abhängen
vorziehen, als ein Optimierungsverfahren, wie es nachfolgend näher erörtert wird.
-
Wenn
ein Ladebefehl in einem Pfad gefunden wird, der zu verkürzen ist,
bestimmt der Kompilierer als Nächstes
bei Schritt 521, welche Berechnungsbefehle von den Daten
abhängen,
die durch den Ladebefehl gelesen werden. Die Berechnungen sind abhängig, falls
dieselben die Verwendung eines Werts erfordern, der sich aus dem
Abschluss des Ladebefehls ergibt.
-
Bei
Schritt 524 wird der Ladebefehl von seiner Position in
der geplanten Befehlssequenz entfernt. Bei Schritt 527 werden
die Berechnungen, die von dem Ladebefehl abhängig sind (identifiziert in Schritt 521),
vorgezogen, um dem Ladebefehl zu folgen, so dass sowohl der Ladebefehl
als auch davon abhängige
Berechnungen auf dem Ladebefehl vorgezogen werden, um eine Optimierung
der Befehlssequenz zu ermöglichen.
Der Kompilierer bewegt den Ladebefehl, der mit „ld.a" gekennzeichnet ist, nach vorne zu einer
Position, wo die Ausführung
desselben zu einer verbesserten Gesamtleistung des Programms führen kann.
-
Wie
es oben erörtert
wurde, kann ein Speicherbefehl in einem Pfad des Abhängigkeitsdiagramms
existieren, vor dem Ladebefehl „ld.a", und es kann sein, dass der Kompilierer
nicht in der Lage ist, zu bestimmen, ob der Lade- und Speicherbefehl
kollidieren (d. h. die gleiche Speicherposition verwenden). Bei
Schritt 530 bestimmt der Kompilierer, ob es eine absolute
Sicherheit gibt, dass der Lade- und der Speicherbefehl nicht kollidieren.
-
Wenn
nicht sicher bestimmt werden kann, dass der Lade- und Speicherbefehl
vor den derselbe bewegt wird, nicht kollidieren, wird bei Schritt 533 der Ladebefehl,
der bei Schritt 524 entfernt wurde, mit einem Prüfbefehl
ersetzt, wie z. B. einem chk.a-Befehl, die oben in Verbindung mit 5 und 6 beschrieben
ist. Der chk.a-Befehl ersetzt den Ladebefehl und wird durchgeführt (wie
nachfolgend beschrieben), wo der Ladebefehl geplant gewesen wäre, falls
er nicht vorgezogen worden wäre.
-
Bei
Schritt 536 erzeugt der Kompilierer Wiederherstellungscode
für den
vorgezogenen Ladebefehl und die Berechnungen, die von dem vorgezogenen
Ladebefehl abhängen,
die bei Schritt 527 vorgezogen wurden. Der Wiederherstellungscode wird durch
den chk.a-Befehl aufgerufen, falls notwendig, wie es nachfolgend
beschrieben ist.
-
Wenn
in dem längsten
kritischen Pfad bei Schritt 512 kein Ladebefehl gefunden
wird, oder wenn bei Schritt 530 bestimmt wird, dass der
Kompilierer absolut sicher ist, dass der Ladebefehl nicht vor einen
Speicherbefehl vorgezogen wurde, mit dem derselbe kollidieren wird
(so dass kein Prüfbefehl oder
Wiederherstellungscode notwendig sind), oder nachdem der Wiederherstellungscode
bei Schritt 536 erzeugt wurde, dann fährt der Prozess bei Schritt 539 fort,
wobei der Kompilierer bestimmt, ob ein längster kritischer Pfad verbleibt,
der potentiell optimiert werden kann. Der Kompilierer kann jeden
der nächst-längsten Pfade
in dem Programm optimieren, bis der Kompilierer so viel wie möglich von
dem Quellprogramm optimiert, wodurch die Parallelität der Ausführung des
Quellprogramms verbessert wird.
-
Wenn
bei Schritt 539 bestimmt wird, dass der Kompilierer das
Programm nicht weiter optimieren kann, schreitet der Prozess zu
Schritt 542 fort, wobei der Kompilierer die optimierten
Befehlsequenzen für die
Ausführung
plant. Wenn der Kompilierer jedoch bei Schritt 539 bestimmt,
dass es einen längsten
kritischen Pfad gibt, der verbleibt, und der potentiell optimiert
werden kann, identifiziert der Kompilierer bei Schritt 506 den
nächst-längsten Pfad.
Auf diese Weise fährt
der Prozess fort, bis alle Pfade in dem Diagramm optimiert sind,
die optimiert werden können.
-
Bei
Schritt 542 plant der Kompilierer die Ausführung des
Befehls, um jegliche Änderungen
der Ausführungsreihenfolge
zu reflektieren, wie sie durch die oben beschriebenen Optimierungsprozeduren ausgeführt werden.
Der Kompilierer kann die Ausführung
der Befehle in dem Programm auf eine Anzahl von Weisen planen, wodurch
er potentiell die parallelen Ausführungseinheiten nutzt, und
die vorliegende Erfindung ist nicht auf einen bestimmten Zeitplanmechanismus
begrenzt. Für
das oben in 6 beschriebene Beispiel ist
der resultierende optimierte Code in 7 gezeigt,
und der Wiederherstellungscode ist als Befehle I24r, I26r und I23r
notiert.
-
9 ist
ein Flussdiagramm, das eine Routine darstellt, die durch ein Computersystem
ausgeführt
wird, wenn eine Befehlssequenz ausgeführt wird, die durch Techniken
optimiert wird, wie z. B. diejenigen, die oben in Verbindung mit 8 beschrieben
sind, die das Vorziehen eines Ladebefehls und abhängiger Berechnungen
außerhalb
der Reihenfolge vor einem Speicherbefehl umfassen.
-
Die
Ausführung
der geplanten Befehlssequenz wird bei Schritt 603 begonnen.
Während
der Ausführung
der Befehlssequenz wird der vorgezogene Ladebefehl (z. B. Id.a,
in 7) bei Schritt 606 ausgeführt. Nachdem
der vorgezogene Ladebefehl ausgeführt wurde, wird die ALAT aktualisiert,
um den Bereich von Speicherpositionen aufzuzeichnen, der durch den
vorgezogenen Ladebefehl gelesen wird (z. B. die Adresse in r2),
der bei Schritt 609 ausgeführt wird. In die ALAT wird
ein Eintrag gemacht, um es einem später ausgeführten Speicherbefehl, wie z.
B. dem in Schritt 618 ausgeführten Speicherbefehl, zu ermöglichen,
zu bestimmen, ob der vorgezogene Ladebefehl und die Speicherbefehle,
auf eine gemeinsame Speicherstelle zugegriffen haben. Die beschriebenen
Ausführungsbeispiele
sind nicht auf eine bestimmte ALAT-Struktur begrenzt, da jede Struktur
verwendet werden kann, die es ermöglicht, dass der Bereich von
Speicheradressen eines bestimmten vorgezogenen Ladebefehls und dem
entsprechenden Speicherbefehl verglichen werden kann.
-
Bei
einem in 10 gezeigten Ausführungsbeispiel
umfasst ein Eintrag in die ALAT ein physikalisches Speicheradressfeld
und ein Speicherzugriffsgrößenfeld,
die zusammen den Bereich von zugegriffenen Speicherpositionen definieren.
Die beschriebenen Ausführungsbeispiele
sind nicht auf dieses Verfahren zum Definieren des Bereichs von
Speicherpositionen begrenzt, da zahlreiche andere Techniken verwen det
werden können.
Beispielsweise kann der zugegriffene Speicherbereich durch Anfangs-
und Endspeicheradressen, oder durch eine Speicherendadresse und
einen Bereich identifiziert werden. Bei dem in 10 gezeigten
Ausführungsbeispiel
umfasst die ALAT auch ein Feld für
ein gültiges
Bit, das verwendet wird, um anzuzeigen, ob der Eintrag gültig ist.
Wie es nachfolgend erörtert
wird, gibt es bei einem Ausführungsbeispiel
der Erfindung Zeiten (z. B. Kontextwechsel zwischen zwei Anwendungen), wenn
es wünschenswert
ist, die Einträge
in der ALAT ungültig
zu machen. Das gültige
Bit liefert einen praktischen Mechanismus zum Durchführen einer
solchen Ungültigkeitserklärung.
-
Bei
einem Ausführungsbeispiel
der Erfindung kann es gleichzeitig mehrere Ladebefehle geben, die
jeder vor einen entsprechenden Speicherbefehl vorgezogen wurden.
Wie es nachfolgend erörtert wird,
ist während
der Programmausführung
eine Technik vorgesehen zum Verifizieren, dass zwischen jedem Paar
von Lade- und Speicherbefehlen keine Kollision aufgetreten ist.
Somit umfasst bei einem Ausführungsbeispiel
der Erfindung die ALAT Informastionen, die eindeutig den vorgezogenen
Ladebefehl identifizieren, mit dem dieselbe korrespondiert, so dass
der Eintrag identifiziert werden kann, um eine mögliche Kollision mit dem entsprechenden Speicherbefehl
zu bestimmen. Diese einmalige Identifikation kann auf eine Vielzahl
von Weisen implementiert werden, und die vorliegende Erfindung ist nicht
auf eine bestimmte Implementierung beschränkt. Bei dem in 10 gezeigten
Ausführungsbeispiel
ist der Eintrag für
einen bestimmten vorgezogenen Ladebefehl indexiert, basierend auf
der Registernummer und dem Registertyp (allgemein oder Gleitpunkt),
der bei dem vorgezogenen Ladebefehl verwendet wird. Die Registernummer,
die für
jeden Befehl verwendet wird, wird durch den Kompilierer zugewiesen,
der sicherstellt, dass für
jeden vorgezogenen Ladebefehl ein eindeutiges Register verwendet
wird.
-
Wenn
der vorgezogene Ladebefehl bei Schritt 606 ausgeführt wird
(9), und bevor ein Eintrag in die ALAT durchgeführt wird,
wird auf die ALAT zugegriffen, unter Verwendung der Zielregisternummer
als Index, und die ALAT wird geprüft, um zu bestimmen, ob bereits
ein Eintrag existiert, der der Zielregisternummer entspricht, die
durch den vorgezogenen Ladebefehl verwendet wird. Falls es einen Eintrag
gibt, wird derselbe entfernt, weil er Informationen umfasst, die
sich nicht auf den aktuellen vorgezogenen Ladebefehl beziehen, und
höchstwahrscheinlich
während
der Ausführung
eines früheren vorgezogenen
Ladebefehls eingetragen wurden. Nachdem der bestehende Eintrag von
den Daten von dem vorher ausgeführten
vorgezogenen Ladebefehl gelöscht
wurde, oder wenn ein leerer Schlitz, der der Zielregisternummer
des aktuellen vorgezogenen Ladebefehls entspricht, in der ALAT gefunden
wird, wird ein neuer Eintrag, der durch die Zielregisternummer indexiert
wird, für
den vorliegenden vorgezogenen Ladebefehl durchgeführt.
-
Nachdem
der vorgezogene Ladebefehl ausgeführt wird und die ALAT aktualisiert
ist, werden die Berechnungsbefehle, die von dem Ergebnis des vorgezogenen
Ladebefehls (z. B. I24, I26) abhängen, bei
Schritt 612 ausgeführt.
Bei dem oben erörterten Beispiel
umfassen die abhängigen
Berechnungen einen Addierbefehl I26, wie es in 7 gezeigt
ist. Alle anderen Befehle, die dem vorgezogenen Ladebefehl folgen
und dem Speicherbefehl vorausgehen, über den der Ladebefehl bewegt
wurde, werden bei Schritt 615 ausgeführt.
-
Bei
Schritt 618 wird der Speicherbefehl (z. B. I22), über den
der Ladebefehl vorgezogen wurde, und mit dem der Ladebefehl möglicherweise
kollidieren kann, ausgeführt.
Bei dem in 7 gezeigten Beispiel greift
der Speicherbefehl I24 auf die Adresse in r1 zu. Beim Ausführen des
Speicherbefehls I22 werden alle gültigen Einträge in der
ALAT durchsucht, unter Verwendung der physikalischen Adresse und
Größe der Speicherregion,
die durch den Speicherbefehl beschrieben wird. Diese Suche kann auf
eine Vielzahl von Weisen durchgeführt werden, und die vorliegende
Erfindung ist nicht auf eine bestimmte Technik begrenzt. Bei einem
Ausführungsbeispiel
der vorliegenden Erfindung ist die ALAT als ein voll assoziativer
inhaltsadressierbarer Speicher angeordnet, so dass alle gültigen Einträge gleichzeitig
durchsucht werden. Die Einträge
werden durchsucht, um zu bestimmen, ob eine Kollision aufgetreten
ist zwischen dem Speicherbefehl und irgendeinem vorgezogenen Ladebefehl.
Falls der Bereich des Speicherplatzes eines vorgezogenen Ladebefehls
(z. B. I24) in der ALAT gefunden wird, die dem Bereich des Speicherplatzes
für den
Speicherbefehl überlappt
(z. B. I22), dann ist eine Kollision aufgetreten. Wenn bei einem
Ausführungsbeispiel
der Erfindung eine Kollision erfasst wird, werden die Einträge in der
ALAT für
die Adressen, die den kollidierenden vorgezogenen Ladevorgängen entsprechen,
bei Schritt 621 entfernt, wodurch die Kollision angezeigt wird.
Falls bei Schritt 621 der Speicherplatz, auf den durch
den Speicherbefehl (z. B. I22) zugegriffen wird, nicht mit dem des
vorgezogenen Ladebefehls (z. B. I24) überlappt, verbleiben die Einträge in der
ALAT, die den bestimmten vorgezogenen Ladebefehlen entsprechen,
in der ALAT.
-
Es
sollte klar sein, dass ein Ladebefehl, der vorgezogen wird, vor
mehrere Speicherbefehle bewegt werden kann, von denen jeder potentiell
mit dem Ladebefehl kollidieren kann. Ein einzelner Prüfbefehl
nach einer Sequenz von Speicherbefehlen kann verwendet werden, um
zu erfassen, ob einer der mehreren Speicherbefehle mit dem Ladebefehl kollidiert,
da das Ausführen
jedes Speicherbefehls das Suchen aller Einträge in der ALAT umfasst, um zu
bestimmen, ob eine Kollision aufgetreten ist. Somit ist der Prüfbefehl
unabhängig
von der Anzahl von Speicherbefehlen in dem Programm, da ein getrennter
Prüfbefehl
jeden Ladebefehl ersetzt, der bei Schritt 533 vorgezogen
wird, und jeder Prüfbefehl überprüft die ALAT,
wie es nachfolgend in Schritt 623 beschrieben ist.
-
Es
sollte auch klar sein, dass eine Kollision auftreten kann zwischen
einem vorgezogenen Ladebefehl und einem Speicherbefehl, wie es oben
erörtert
ist, selbst wenn die Anfangsadressen für die Daten, auf die durch
diese Befehle zugegriffen wird, nicht identisch sind. Genauer gesagt,
jeder Befehl kann auf mehrere Datenbytes zugreifen. Somit kann eine
Kollision auftreten, falls es eine Überlappung zwischen dem Bereich
von Speicheradressen gibt, die durch den Datenlesevorgang durch
den vorgezogenen Ladebefehl besetzt werden, und dem Bereich von
Speicheradressen, der durch die Daten besetzt wird, die durch den
Speicherbefehl geschrieben werden. Die Erfassung einer Kollision
kann auf zahlreiche Weisen durchgeführt werden, und die vorliegende
Erfindung ist nicht auf eine bestimmte Implementierung begrenzt.
Beispielsweise kann ein Vollbereichsvergleich durchgeführt werden
zwischen den Adressen für
die Daten, die durch den vorgezogenen Ladebefehl geschrieben werden,
und durch den Speicherbefehl gelesen werden. Ein Vollbereichsvergleich
kann jedoch aufwändig
zu implementieren sein in Hardware. Daher wird gemäß einem
Ausführungsbeispiel
der Erfindung eine Technik verwendet zum Bestimmen von Kollisionen,
ohne einen Vollbereichsvergleich der Adressen für die Daten durchzuführen, auf
die durch den vorgezogenen Ladebefehl und den Speicherbefehl zugegriffen
wird.
-
Gemäß diesem
Ausführungsbeispiel
der vorliegenden Erfindung wird Ausrichten von Daten, die in dem
Speicher gespeichert sind, nach Größe bevorzugt, so dass die Anfangsadresse
für einen
Datenblock vorzugsweise ein gerades Mehrfaches seiner Größe ist.
Beispielsweise wird ein Datenblock, der vier Bytes umfasst, vorzugsweise
bei einer Adresse gespeichert, bei der die zwei niedrigstwertigen
Bits (LSBs) Null sind, ein Block von acht Bytes wird vorzugsweise
bei einer Adresse gespeichert, bei der die drei LSBs Nullen sind
usw. Wenn die Daten nach Größe ausgerichtet
sind, kann eine Kollision erfasst werden durch einfaches Durchführen eines
Direktgleichheitsvergleichs der Anfangsadressen für die Daten, auf
die durch den vorgezogenen Ladebefehl und den Speicherbefehl zugegriffen
wird. Es sollte klar sein, dass ein Direktgleichheitsvergleich wesentlich
weniger aufwändig
in Hardware zu implementieren ist als ein Vollbereichsvergleich.
Falls es einen begrenzten Fehlausrichtungsbetrag gibt, wenn Daten fehlausgerichtet
sind, so dass die fehlausgerichteten Daten in einen größeren, größenausgerichteten
Datenbereich passen können,
dann verarbeitet die Hardware bei einem Ausführungsbeispiel der Erfindung
den Befehl (z. B. einen Ladebefehl), der auf die fehlausgerichteten
Daten zugreift, als ob er auf den größeren, größenausgerichteten Datenbereich
zugreift. Falls beispielsweise ein Ladebefehl auf acht Bytes fehlausgerichteter
Daten im Speicher zugreift, aber die Daten, auf die durch den Ladebefehl
zugegriffen wird, in einen größenausgerichteten 32-Byte-Bereich passen
würden,
dann wird der Ladebefehl so behandelt, als würde er auf 32 Datenbytes zugreifen.
Indem der Befehl so behandelt wird, als würde er einen größeren Block
von größenausgerichteten
Daten verwenden, sollte klar sein, dass es Situationen geben kann,
wo es eine Überlappung
der Datenadressen gibt, auf die durch einen vorgezogenen Ladebefehl
und einen Speicherbefehl zugegriffen wird, aber keine Überlappung
der tatsächlichen Daten
(bei dem obigen Beispiel acht Bytes), auf die tatsächlich durch
einen der Befehle zugegriffen wird, was zu der Erfassung einer falschen
Kollision führt. Diese
Leistungsstrafe ist ein Preis, der bezahlt wird, um die Komplexität der Hardware
zum Erfassen von Kollisionen zu reduzieren. Falls Daten wesentlich fehlausgerichtet
sind und nicht in vernünftig
große größenausgerichtete
Datenbereiche passen, dann verarbeitet die Hardware den Lade- oder
Speicherbefehl nicht. Für
Ladebefehle wird kein Eintrag in die ALAT eingefügt, was bewirkt, dass eine
Kollision angezeigt wird. Obwohl dies dazu führen kann, dass falsche Kollisionen
erfasst werden, ist diese Leistungsstrafe ein Preis, der bezahlt
wird, um die Komplexität der
Hardware zum Erfassen von Kollisionen zu reduzieren. Für Speicherbefehle,
die wesentlich fehlausgerichtet sind, kann der Befehl in eine Sequenz
von kleineren Speicherbefehlen unterteilt werden. Bei einem Ausführungsbeispiel
kann Hardware verwendet werden, um den größeren Speicherbefehl in die
Sequenz von mehreren Speicherbefehlen zu unterteilen. Bei einem
weiteren Ausführungsbeispiel
kann ein fehlausgerichteter Speicherbefehl, der nicht in einen größenausgerichteten
Datenbereich passen kann, eine Unterbrechung bewirken, und das Betriebssystem
handhabt den Speicherbefehl durch Trennen des Speicherbefehls in
eine Sequenz von kleineren Speicherbefehlen. Bei beiden Ausführungsbeispielen
der Handhabung eines fehlausgerichteten Speicherbefehls wird jeder
der kleineren Speicherbefehle in der Sequenz gegen die gültigen Einträge in der
ALAT geprüft,
wie es bei Schritt 618 beschrieben ist. Falls der Bereich
von Speicherplatz für
jeden der kleineren Speicherbefehle den Bereich von Speicherplatz
eines vorgezogenen Ladebefehls überlappt,
dann würde
eine Kollision angezeigt, wie es bei Schritt 621 beschrieben
ist. Somit liefert das Ausführen
von jedem der kleineren Speicherbefehle das gleiche Ergebnis wie
das Ausführen
eines einzigen größeren Speicherbefehls.
-
Bei
einem weiteren Ausführungsbeispiel
der vorliegenden Erfindung werden weitere Einsparungen bei der Hardware,
die verwendet wird, um Kollisionen zu erfassen, erreicht, durch
Verwenden von Teiladressen für
den Gleichheitsvergleich durch Ignorieren von einem oder mehreren
der höchstwertigsten
Bits (MSBs) der Adressen. Das Ignorieren von einem oder mehreren
der MSBs führt
zu einer Reduktion bei der Größe der ALAT
und bei der Hardware, die den Gleichheitsvergleich durchführt, da
weniger Bits für
jeden Eintrag in der ALAG gespeichert werden, und weniger Bits verglichen
werden. Für
eine 64-Bit-Datenadresse können
beispielsweise nur die 20 niedrigstwertigsten Bits (LSBs) des Ladebefehls in
der ALAT gespeichert werden und bei dem Gleichheitsvergleich verwendet
werden.
-
Es
sollte klar sein, dass das Ignorieren von einem oder mehreren der
MSBs zu der Erfassung einiger falscher Kolli sionen führen kann.
Insbesondere wenn die ALAT beim Ausführen eines Speicherbefehls
(z. B. bei Schritt 618) durchsucht wird, können die
vollständigen
Anfangsadressen für
die Daten des Speicherbefehls und die Daten des Ladebefehls identisch
sein für
die LSBs, über
die der Gleichheitsvergleich durchgeführt wird (z. B. die 20 LSBs),
aber kann sich für
ein oder mehrere der MSBs unterscheiden, die ignoriert werden. Wenn
dies auftritt, wird die Routine von 9 ablaufen,
als ob eine Kollision bereits aufgetreten ist, z. B. durch Schalten
des Steuerflusses zu dem Wiederherstellungscode. Es sollte klar
sein, dass falsche Erfassungen daher zu einer Leistungsstrafe führen, aufgrund
der Wiederherstellung von Kollisionen, die nicht wirklich stattgefunden haben.
Diese Leistungsstrafe ist ein Preis, der gezahlt wird, um die Komplexität der Hardware
zum Erfassen von Kollisionen zu reduzieren. Ein Gleichgewicht zwischen
diesen wettstreitenden Faktoren kann berücksichtigt werden, wenn bestimmt
wird, wie viele (falls welche) MSBs in dem Erfassungsschema zu ignorieren
sind.
-
Bei
Schritt 623 wird der chk.a-Befehl (z. B. I25) für den vorgezogenen
Ladebefehl ausgeführt, der
bei Schritt 606 ausgeführt
wird. Bei einem Ausführungsbeispiel überprüft der chk.a-Befehl
die ALAT, um zu bestimmen, ob eine Kollision aufgetreten ist, durch
Bestimmen, ob es einen Eintrag für
den vorgezogenen Ladebefehl (z. B. I24) gibt. Unter Verwendung der
Identität
des Zielregisters und des Registertyps, der durch den vorgezogenen
Ladebefehl (z. B. I24) verwendet wurde, für den bei Schritt 621 Informationen
in der ALAT aktualisiert wurden, als einen Index, überprüft der chk.a-Befehl
die ALAT. Falls ein Eintrag in der ALAT gefunden wird, der dem bestimmten
vorgezogenen Ladebefehl entspricht, der durch den chk.a-Befehl ersetzt
wurde, dann erkennt der chk.a-Befehl bei Schritt 624, dass
der Speicherbefehl (z. B. I22) und der Ladebefehl (z. B. I24), der über den
Speicherbefehl vorgezogen wurde, nicht kollidierten. Daher sind
die Daten, die durch den Speicherbefehl gelesen werden, gültig, und
die Routine schreitet fort, um die Ausführung der Befehlssequenz bei
Schritt 630 fertig zu stellen.
-
Falls
jedoch der chk.a-Befehl die ALAT bei Schritt 624 überprüft und keinen
Eintrag in der ALAT sieht, der der Registeradresse entspricht, die
durch den vorgezogenen Ladebefehl (z. B. I24) verwendet wird, dann
bestimmt der chk.a-Befehl (z. B. I25), dass der Speicher- und der
vorgezogene Ladebefehl auf den gleichen Speicherplatz zugegriffen
haben können
(d. h. kollidierten). Somit werden weitere Schritte durchgeführt, um
die Genauigkeit des vorgezogenen Ladebefehls und der Berechnungsbefehle,
die ausgeführt
wurden, auf der Basis des vorgezogenen Ladebefehls (z. B. I24) sicherzustellen.
Wenn bei einem Ausführungsbeispiel
eine mögliche
Kollision erfasst wird, wird der Steuerfluss des Programms geändert, um
Wiederherstellungscode auszuführen.
Wie es oben erörtert
wurde, kann dies auf zahlreiche Weisen durchgeführt werden (z. B. durch Verzweigen
oder Verwenden einer Ausnahmehandhabungstechnik). Es sollte klar
sein, dass die ALAT mit einer Anzahl von Einträgen implementiert werden kann,
die nicht ausreichend sein können,
um alle der vorgezogenen lokalen Befehle zu unterstützen, die
in einem Programm enthalten sein können, das ausgeführt wird. Bei
dem in 9 gezeigten Ausführungsbeispiel verzweigt der
chk.a-Befehl zu dem Wiederherstellungscode bei Schritt 633 (9).
Ein Beispiel von Wiederherstellungscode ist in 7 gezeigt,
als Befehle I24r, I26r und I23r, die im Wesentlichen Kopien der Kommentare
I24, I26 und I23 sind.
-
Bei
Schritt 636 wird der Ladebefehl (z. B. I24), der bei Schritt 524 vorgezogen
wurde, wiederausgeführt.
Bei Schritt 639 werden Befehle, die von dem vorgezogenen
Ladebefehl (z. B. I24) abhängen, wiederausgeführt. Bei
dem Beispiel von 7 sind der wiederausgeführte Ladebefehl
I24r und der abhängige
Addierbefehl I26r gezeigt. Diese Befehle werden nach dem Speicherbefehl
wiederausgeführt, um
die ordnungsgemäßen Ergebnisse
des Ladebefehls I24r und seiner abhängi gen Berechnungen I26r zu
liefern. Bei einem Ausführungsbeispiel
kann der Wiederherstellungscode jede Kombination von Befehlen sein,
die durch den Kompilierer bestimmt werden, die das gleiche Ergebnis
liefert wie der ursprüngliche
ausgeführte
Ladebefehl und die abhängigen
Berechnungsbefehle.
-
Bei
Schritt 642 kehrt der Steuerfluss von dem Wiederherstellungscode
zurück
zu dem kompilierten Ausführungsplan.
Dies kann beispielsweise durchgeführt werden unter Verwendung
eines Verzweigungsbefehls, wie z. B. I23r in 7. Als Nächstes fährt die Ausführung der
geplanten Befehle fort, bis zum Ende des Programms bei Schritt 630.
-
Bei
einem Ausführungsbeispiel
hat die ALAT beispielsweise Raum für Einträge, die 32 vorgezogenen Befehlen
entsprechen. Falls es mehr als 32 vorgezogene Befehle in einem ausgeführten Programm gibt,
dann hat die ALAT nicht ausreichend Raum für Informationen, die sich auf
alle die vorgezogenen Befehle beziehen. Wenn die ALAT voll ist und
ein neuer vorgezogener Befehl ausgeführt wird, kann ein Austauschschema
verwendet werden, um einen gültigen Eintrag
in der ALAT herauszunehmen, um Platz für den neuen Befehl zu machen.
Wenn ferner bei einem Ausführungsbeispiel
der vorliegenden Erfindung die Ausführung bei der Laufzeit zwischen
Prozessen schaltet (wie z. B. zwischen getrennten kompilierten Programmen),
können
die Einträge
in der ALAT für spätere Wiederherstellung
gespeichert werden, oder können
ungültig
gemacht werden. Somit kann in einigen Fällen ein chk.a-Befehl keinen
Eintrag für
einen bestimmten vorgezogenen Befehl finden, auch wenn für diesen
Befehl keine Kollision aufgetreten ist.
-
Wie
es oben erörtert
wurde, ist das System nicht auf eine bestimmte ALAT-Struktur beschränkt und
kann andere alternative Ausführungsbeispiele umfassen,
zum Bestimmen, ob es eine Kollision zwischen einem Lade- und einem
Speicherbefehl gibt. Beispielsweise können andere Datenstrukturen oder Vergleichsschaltungen
verwendet werden. Außerdem
kann eine ALAT- oder andere Struktur, die verwendet werden, in der
Größe und der
Anzahl von verwendeten Feldern variieren. Außerdem können getrennte ALATs oder Datenstrukturen
für jeden
von mehreren Registersätzen
verwendet werden. Beispielsweise kann bei einem Ausführungsbeispiel eine
ALAT verwendet werden, für
allgemeine und Gleitpunktregistersätze.
-
Obwohl
das bevorzugte Ausführungsbeispiel mit
Bezugnahme auf verschobene Ausnahmehandhabung und Datenspekulation
erklärt
wurde, ist es nicht darauf beschränkt. Allgemein umfasst die
vorliegende Erfindung jeden Typ von Befehlssegment, der spekulativ
ausgeführt
wird, das Verifizieren der Integrität der Ausführung der Befehle, die spekulativ ausgeführt wurden,
und das Ausführen
von Wiederherstellungscode zum Korrigieren aller erfassten Probleme.
Diese selbe kann erweitert werden, um einen Befehl zu umfassen,
der sowohl steuer- als auch datenspekulativ ist.
-
Die Übertragung
der Steuerung von den chk.s- und chk.a-Befehlen zu dem Wiederherstellungscode
kann auf eine Vielzahl von Weisen implementiert werden. Beispielsweise
können
die chk.s- und chk.a-Befehle sich jeweils als ein Verzweigungsbefehl
verhalten, wo die Adresse des ersten Befehls in dem Wiederherstellungscode
in dem chk.s- oder chk.a-Befehl selbst enthalten ist (wie es in 5 gezeigt
ist). Alternativ können
der chk.s- oder chk.a-Befehl eine bestimmte Ausnahme erzeugen, und
die Ausnahmehandhabungsroutine kann einen Wert in dem chk.s- oder
chk.a-Befehl verwenden, um den entsprechenden Wiederherstellungscode
zu identifizieren, und dann die Steuerung zu diesem Wiederherstellungscode übertragen,
mit einem Trampolinmechanismus, wie er z. B. in den Flussdiagrammen von 2 und 3 dargestellt
ist, die oben beschrieben sind. Die Ausnahmehandhabungsroutine kann
auch die Adresse des chk.a- oder chk.s-Befehls verwenden, die die
Adressposition in dem Speicher ist, wo der Befehl gespeichert wird,
um die Position des Wiederherstel lungscodes zu identifizieren. Der Wiederherstellungscode
kann auf einer Tabelle basieren, die durch den Kompilierer erzeugt
wird, der Adressen von Prüfbefehlen
umfasst, die durch den Kompilierer zu einem kompilierten Quellprogramm hinzugefügt wurden.
Der ausgeführte
Wiederherstellungscode wird daher dadurch identifiziert, welcher Prüfbefehl
ausgeführt
wird.
-
Das
System ermöglicht
es, dass Befehle außer
der Reihenfolge vorgezogen werden, selbst wenn der Kompilierer nicht
sicher ist, dass der vorgezogene Befehl nicht mit einem späteren Befehl
kollidiert. Wie es oben erörtert
wurde, können
einige herkömmliche
Kompilierer einen Signalladebefehl vorzuziehen, der vor einen Speicherbefehl
bewegt wurde, selbst wenn es nicht sicher ist, dass der Lade- und
Speicherbefehl nicht kollidieren. Falls es während der Laufzeit eine Kollision
gab, würde
der Ladebefehl in Reihe mit dem kompilierten Ausführungsplan
erneut ausgeführt.
Im Gegensatz dazu wird bei einem Ausführungsbeispiel der vorliegenden
Erfindung eine Optimierung der Befehlsausführung erreicht durch Vorziehen
von nicht nur einem Ladebefehl vor dem Speicherbefehl, sondern auch
von Berechnungen, die von demselben abhängen. Dies ermöglicht es
einem Kompilierer und Zeitplaner, mehrere Ausführungseinheiten zu einem Zeitpunkt
am effizientesten zu verwenden. Ferner, anstatt den Ladebefehl einfach
neu auszuführen,
wenn eine Kollision auftritt, wird ein Prüfbefehl ausgeführt, der
bestimmt, ob es eine Kollision gab, und der Steuerfluss wird zum
Wiederherstellungscode geändert,
der den Ladebefehl und seinen abhängigen Berechnungen umfasst.
Somit können
mehrere Abschnitte des Codes unabhängig und parallel ausgeführt werden.
-
Das
System ermöglicht
Flexibilität
auf Seiten des Kompilierers bezüglich
der Zuordnung zwischen chk-Befehlen, der spekulativen Abhängigkeitskette und
dem Wiederherstellungscode. Das hierin enthaltene Beispiel ist relativ
einfach, aber sehr viel komplexere Codekonfigurationen sind möglich, wie
z. B. wenn eine spekulative Abhängigkeitskette
nicht aus einer einzelnen linearen Sequenz von Befehlen besteht,
wie bei dem Beispiel in 7, sondern mehrere Sequenzen
enthält,
oder wenn zwei oder mehr spekulative Abhängigkeitsketten voneinander
abhängen.
Die vorliegende Erfindung ermöglicht
wesentliche Flexibilität
beim Adressieren dieser verschiedenen Konfigurationen und ermöglicht dadurch
zukünftige
Verfeinerungen bei der Verwendung von Wiederherstellungscode, wenn
sich das Verständnis
der statischen Spekulation erweitert.
-
Das
System ermöglicht
einen großen
Grad an Flexibilität
bezüglich
der Anzahl und Konfiguration von chk-Befehlen. Beispielsweise kann
ein einzelner chk.s konfiguriert sein, um den Bestimmungsort von einem
der Befehle entlang der spekulativen Abhängigkeitskette zu lesen, oder
mehrere chk.s-Befehle können
emittiert werden, wobei jeder einen anderen Bestimmungsort liest.
Jeder chk.s-Befehl kann auch den gleichen oder einen anderen Satz
von Wiederherstellungscodebefehlen aufrufen.
-
Das
System umfasst auch alternative Ausführungsbeispiele zum Erfassen
des Vorliegens von DETs. Beispielsweise gibt es bei einem Ausführungsbeispiel
keinen expliziten chk.s-Befehl.
Statt dessen werden DETs erfasst durch jeden nicht-spekulativen Befehl
als Teil der normalen Ausführung
von nicht-spekulativen Befehlen. Wenn bei diesem Ausführungsbeispiel
ein nicht-spekulativer Befehl auf ein DET trifft, wird eine Ausnahme
erzeugt, die die verschobene Ausnahme adressiert. Bei einem weiteren darstellenden
Ausführungsbeispiel
werden DETs in zweckgebundenen Registern oder Speicher gespeichert,
anstatt den Bestimmungsorten jedes Befehls.
-
Bei
einem weiteren Ausführungsbeispiel kann
der nicht-spekulative
Wiederherstellungscode der gleiche Code sein wie der spekulative
In-Line-Code. Beispielsweise kann eine Architektur verwendet werden,
bei der jeder Befehl als spekulativ oder nicht-spekulativ markiert
ist, auf der Basis eines Spekulationsflags, das in dem Befehl enthalten
ist. Ein Kompilierer kann beispielsweise ein Segment von Befehlen
als spekulativ planen, und ein DET kann erfasst werden, nachdem
diese Befehle ausgeführt wurden,
und dadurch eine verschobene Ausnahmehandhabungsroutine aktivieren.
Die verschobene Ausnahmehandhabungsroutine kann einfach das Spekulationsflag
des spekulativen Befehls umschalten, um denselben in nicht-spekulative
Befehle umzuwandeln, die Befehle neu auszuführen, die Ausnahme zu verarbeiten,
die vorher verschoben wurde, und die Flags zurück umzuschalten, um die Befehle zurück zu spekulativen
Befehlen umzuwandeln. Obwohl dieses Ausführungsbeispiel dem Kompilierer weniger
Flexibilität
beim Planen von Wiederherstellungscode liefert, kann es auch zu
wesentlichen Einsparungen bei der Speichermenge führen, die
durch den Code verbraucht wird. Außerdem muss das Spekulationsflag
nur in dem Cache-Speicher nicht umgeschaltet werden, wodurch die
Zeit minimiert wird, die erforderlich ist, um die Spekulationsflags
umzuschalten.
-
Bei
einem ähnlichen
Ausführungsbeispiel kann
ein Registersatz definiert sein, um Codesegmente zu identifizieren,
in denen spekulative Befehle als nicht-spekulativ ausgeführt werden
sollten. Dieses Ausführungsbeispiel
wird im Wesentlichen wie oben beschrieben funktionieren, außer dass
anstatt dem Umschalten der Spekulationsflags der Befehle, die nicht-spekulativ
auszuführen
sind, die Register mit Indexen geladen würden, die die Befehle identifizieren,
die nicht-spekulativ auszuführen
sind.
-
Fachleute
auf dem Gebiet der Chemie, Mechanik, Elektromechanik, Elektrik und
Computertechnik werden ohne weiteres erkennen, dass die vorliegende
Erfindung in einer sehr großen
Vielzahl von Ausführungsbeispielen
implementiert werden kann.