-
ERFINDUNGSGEBIET
-
Die
vorliegende Erfindung betrifft Mikroprozessorsysteme und insbesondere
eine Thread-Identifikation
in einem Multithread-Prozessor.
-
ALLGEMEINER STAND DER TECHNIK
-
Moderne
Computersysteme verwenden zum Vornehmen einer Programmausführung eine
Vielzahl verschiedener Mikroprozessorarchitekturen. Jede Mikroprozessorarchitektur
ist konfiguriert, Programme auszuführen, die aus einer Reihe von
Makroanweisungen und Mikroanweisungen bestehen. Viele Makroanweisungen
werden vor der Verarbeitung in eine Sequenz aus Mikroanweisungen übersetzt
oder decodiert. Mikroanweisungen sind einfache Maschinenanweisungen,
die von einem Mikroprozessor direkt ausgeführt werden können.
-
Zur
Erhöhung
der Verarbeitungsleistung verwenden die meisten Mikroprozessoren
mehrere Pipelines wie etwa eine Integer-Pipeline und eine Lade-/Speicher-Pipeline
zum Verarbeiten der Makro- und Mikroanweisungen. Jede Pipeline besteht
in der Regel aus mehreren Stufen. Jede Stufe in einer Pipeline arbeitet
parallel zu den anderen Stufen. Jede Stufe arbeitet jedoch an einer
anderen Makro- oder Mikroanweisung. Pipelines sind üblicherweise
synchron bezüglich
des Systemtaktsignals. Deshalb ist jede Pipeline-Stufe so ausgelegt,
daß sie
ihre Funktion in einem einzelnen Taktzyklus ausführt. Somit bewegen sich die
Anweisungen mit jeder aktiven Taktflanke eines Taktsignals durch
die Pipeline. Einige Mikroprozessoren verwenden asynchrone Pipelines. Zwischen
Pipeline-Stufen werden anstelle eines Taktsignals Handshake-Signale
verwendet, um anzugeben, wann die verschiedenen Stufen bereit sind, neue
Anweisungen anzunehmen. Die vorliegende Erfindung kann mit Mikroprozessoren
verwendet werden, die entweder synchrone und/oder asynchrone Pipelines
verwenden.
-
1 zeigt
eine Anweisungsabhol- und -ausgabeeinheit mit einer Anweisungsabholstufe (I-Stufe) 105 und
einer Vordecodierstufe (PD-Stufe) 110, die über einen
Anweisungspuffer 115 an eine typische vierstufige Integer-Pipeline 120 für einen
Mikroprozessor gekoppelt sind. Die Integer-Pipeline 120 umfaßt eine
Decodierstufe (D-Stufe) 130, eine Ausführ-Eins-Stufe (E1-Stufe) 140,
eine Ausführ-Zwei-Stufe
(E2-Stufe) 150 und eine Rückschreibstufe (W-Stufe) 160.
Die Anweisungsabholstufe 105 holt zu verarbeitende Anweisungen
ab. Die Vordecodierstufe 110 vordecodiert Anweisungen und speichert
sie in den Anweisungspuffer. Sie gruppiert auch Anweisungen so,
daß sie
in der nächsten
Stufe an eine oder mehrere Pipelines ausgegeben werden können. Idealerweise
werden mit jedem Taktzyklus Anweisungen in die Integer-Pipeline 120 ausgegeben.
Jede Anweisung durchläuft
die Pipeline und wird so wie erforderlich von jeder Stufe verarbeitet.
Bei idealen Betriebsbedingungen verarbeitet die Integer-Pipeline 120 somit
simultan vier Anweisungen. Viele Bedingungen, wie unten erläutert, können jedoch
den idealen Betrieb der Integer-Pipeline 120 verhindern.
-
2 zeigt
eine herkömmliche
vierstufige Lade-/Speicher-Pipeline 200 für einen
Mikroprozessor, gekoppelt an ein Speichersystem 270, eine
Anweisungsabholstufe 105 und eine Vordecodierstufe 110.
Die Lade-/Speicher-Pipeline 200 enthält eine Decodierstufe (D-Stufe) 230,
eine Ausführ-Eins-Stufe
(E1-Stufe) 340, eine Ausführ-Zwei-Stufe (E2-Stufe) 250 und
eine Rückschreibstufe
(W-Stufe) 260. Bei einer Ausführungsform enthält das Speichersystem 270 einen
Datencache 274 und einen Hauptspeicher 278. Andere
Ausführungsformen
des Speichersystems 270 können als ein Notizblockspeicher
unter Verwendung von SRAMs konfiguriert sein. Weil Speichersysteme,
Datencaches und Notizblockspeicher in der Technik wohlbekannt sind,
werden die Funktion und die Leistung des Speichersystems 270 nicht
ausführlich
beschrieben.
-
Die
Lade-/Speicher-Pipeline 200 ist spezifisch so ausgelegt,
daß sie
Lade- und Speicheranweisungen durchführt. Die Decodierstufe 230 decodiert
die Anweisung und liest die nicht gezeigte Registerdatei für die benötigten Informationen
hinsichtlich der Anweisung. Die Ausführ-Eins-Stufe 240 berechnet
Speicheradressen für
die Lade- oder Speicheranweisungen. Weil die Adresse in der Ausführ-Eins-Stufe berechnet
wird und Ladeanweisungen nur die Andresse liefern, konfiguriert
die Ausführ-Eins-Stufe 240 das
Speichersystem 270 so, daß die entsprechenden Daten
beim nächsten
aktiven Taktzyklus für
ein Laden aus dem Speicher bereitgestellt werden. Für Speicheranweisungen
jedoch stehen in der Regel die zu speichernden Daten nicht bei der
Ausführ-Eins-Stufe 240 zur
Verfügung.
Für Ladeanweisungen
ruft die Ausführ-Zwei-Stufe 250 Informationen
von der entsprechenden Stelle im Speichersystem 270 ab.
Für Speicheranweisungen
bereitet sich die Ausführ-Zwei-Stufe 250 vor,
die Daten an eine entsprechende Stelle zu schreiben. Beispielsweise
konfiguriert für
das Speichern in einem Speicher die Ausführ-Zwei-Stufe 250 das
Speichersystem 270, die Daten bei der nächsten aktiven Taktflanke zu
speichern. Für
Registerladeoperationen schreibt die Rückschreibstufe 260 den
entsprechenden Wert in eine Registerdatei. Indem sowohl eine Lade-/Speicher-Pipeline
als auch eine Integer-Pipeline enthalten sind, wird die Gesamtleistung
eines Mikroprozessors verbessert, weil die Lade-/Speicher-Pipeline
und die Integer-Pipelines parallel arbeiten können.
-
Wenngleich
das Pipelining den Gesamtdurchsatz in einem Prozessor erhöhen kann,
führt das
Pipelining auch Datenabhängigkeitsprobleme zwischen
Anweisungen in der Pipeline ein. Wenn beispielsweise auf die Anweisung „LD D0,
[A0]", was bedeutet,
das Datenregister D0 mit dem Wert bei der Speicheradresse A0 zu
laden, „MUL
D2, D0, D1" folgt,
was bedeutet, den Wert in dem Datenregister D0 mit dem Wert im Datenregister
D1 zu multiplizieren und das Ergebnis in Datenregister D2 zu speichern,
dann kann „MUL
D2, D0, D1" erst
ausgeführt werden,
wenn „LD
D0, [A0]" abgeschlossen
ist. Ansonsten kann „MUL
D2, D0, D1" möglicherweise
einen veralteten Wert im Datenregister D0 verwenden. Ein Anhalten
der Pipeline zum Verzögern
der Ausführung
von „MUL
D2, D0, D1" würde jedoch
Prozessorzyklen vergeuden. Viele Datenabhängigkeitsprobleme können gelöst werden
durch Weiterleiten von Daten zwischen Pipeline-Stufen. Beispielsweise
könnte die
Pipeline-Stufe mit dem geladenen Wert von [A0], auf das Datenregister
D0 zielend, den Wert an eine Pipeline-Stufe mit „MUL D2, D0, D1" weiterleiten, um das
Datenabhängigkeitsproblem
ohne Anhalten der Pipeline zu lösen.
-
Im
Idealfall können
die Integer-Pipeline 120 und die Lade-/Speicher-Pipeline 200 bei
jedem Taktzyklus Anweisungen ausführen. Es können jedoch viele Situationen
eintreten, die bewirken, daß Teile der
Integer-Pipeline 120 oder Lade-/Speicher-Pipeline 200 anhalten,
was die Leistung des Mikroprozessors herabsetzt. Ein übliches
Problem, das das Anhalten einer Pipeline verursacht, ist die durch
Cache-Misses verursachte Latenz im Speichersystem 270.
Beispielsweise lädt
eine Lade-Anweisung „LD D0,
[A0]" Daten von
der Adresse A0 des Speichersystems 270 in das Datenregister
D0. Wenn sich der Wert für
die Adresse A0 in einem Datencache 274 befindet, kann der
Wert im Datenregister D0 einfach durch den Datenwert für die Adresse
A0 im Datencache 274 ersetzt werden. Wenn sich jedoch der
Wert für
die Adresse A0 nicht im Datencache 274 befindet, muß der Wert
aus dem Hauptspeicher erhalten werden. Somit kann das Speichersystem 270 verursachen,
daß die
Lade-/Speicher-Pipeline 200 anhält, wenn der Cache-Miss eine
Auffülloperation
verursacht. Wenn der Cache weiterhin keinen leeren Satz aufweist
und die vorausgegangenen Cachedaten schmutzig sind, würde der
Wiederauffülloperation eine
Rückschreiboperation
vorausgehen müssen.
-
Anstatt
die Pipeline anzuhalten und Prozeßzyklen zu vergeuden, können einige
(als Multithread-Prozessoren bezeichnete) Prozessoren von einem
aktuellen Thread zu einem zweiten Thread umschalten, der die Prozessorzyklen
nutzen kann, die in Einzelthread-Prozessoren
vergeudet worden wären.
Insbesondere hält
bei Multithread-Prozessoren der Prozessor den Zustand von mehreren
aktiven Threads, die unabhängig
ausgeführt
werden können. Wenn
einer der Threads blockiert wird, beispielsweise aufgrund eines
Cache-Miss, kann ein anderer Thread ausgeführt werden, so daß keine
Prozessorzyklen vergeudet werden. Zudem kann das Thread-Umschalten
auch durch Zeitgeber-Interrupts und Fortschrittsüberwachungssoftware in einem Echtzeit-Kernel bewirkt werden.
Weil der Prozessor nicht durch das Warten auf einen blockierten
Thread Zyklen vergeuden braucht, wird die Gesamtleistung des Prozessors
erhöht.
Verschiedene Threads arbeiten jedoch im allgemeinen an verschiedenen
Registerkontexten. Somit sollte die Datenweiterleitung zwischen
Threads vermieden werden.
-
Ein
weiteres verwandtes Problem wird durch Traps verursacht. Traps werden
im allgemeinen durch Fehlerzustände
verursacht, die zu einer Umleitung des Programmflusses zum Ausführen eines Trap-Handlers
führen.
Die Fehlerzustände
können
in verschiedenen Pipeline-Stufen auftreten und müssen im Fall des simultanen
Auftretens priorisiert werden. Synchrone Traps müssen zum Anweisungsfluß synchron
sein, was bedeutet, daß auf
die Anweisung, die die Trap verursachte, direkt der Trap-Handler
in der Programmausführung
folgt. Asynchrone Traps werden üblicherweise
einige Zyklen nach der Detektierung der Trap bearbeitet. Bei einem
Multithread-Prozessor muß ein
Trap-Handler in der Lage sein, eine Trap zu dem Thread, der die
Trap verursachte, zu korrelieren. Somit gestatten die meisten herkömmlichen
Prozessoren, die Datenweiterleitung verwenden oder synchrone Traps
unterstützen,
nicht die Koexistenz von mehreren Threads in der gleichen Pipeline.
Bei diesen Prozessoren werden Verarbeitungszyklen während einer
Thread-Umschaltung vergeudet, damit die Pipelines den aktuellen
Thread entleeren können,
bevor zu dem neuen Thread umgeschaltet wird. Andere herkömmliche
Prozessoren gestatten die Koexistenz von mehreren Threads in der Pipeline,
unterstützen
aber nicht die Datenweiterleitung und synchrone Traps;
US-B1-6,470,443 offenbart
einen derartigen Prozessor.
-
Ein
weiteres Problem mit herkömmlichen Multithread-Prozessoren besteht
darin, daß das
Programm-Tracing aufgrund des Thread-Umschaltens kompliziert wird.
Herkömmliche
eingebettete Prozessoren enthalten einen Programm-Trace-Ausgang
für Debugging-
und Entwicklungszwecke. Im allgemeinen ist ein Programm-Trace eine Liste
aus Einträgen, die
die von der Anweisungsabhol- und -ausgabeeinheit ausgegebenen tatsächlichen
Anweisungen mit dem Programmzähler
zu dem Zeitpunkt verfolgt, wo jede Anweisung ausgegeben wird. Für Multithread-Prozessoren
jedoch wäre
eine Liste aus Programmanweisungen ohne Korrelation zu den die Anweisung
besitzenden tatsächlichen
Threads für
das Debugging nutzlos.
-
Somit
existiert eine Notwendigkeit für
ein Verfahren oder System, durch das Pipelines mehrere Threads ohne
die Einschränkungen
herkömmlicher Systeme
bezüglich
Programm-Tracing, Datenweiterleitung und Thread-Bearbeitung aufweisen können.
-
KURZE ZUSAMMENFASSUNG
-
Dementsprechend
enthält
ein Multithread-Prozessor gemäß der vorliegenden
Erfindung, wie in den Ansprüchen
1 und 7 dargelegt, eine Thread-ID für jede Anweisung oder jeden
Operanden in einer Pipeline-Stufe. Eine Datenweiterleitung wird nur
zwischen Pipeline-Stufen mit der gleichen Thread-ID durchgeführt. Zudem
wird die Beziehung zwischen Threads und Traps leicht aufrechterhalten, weil
die Thread-ID für
jede Anweisung, die die Trap verursachen kann, an jeder Pipeline-Stufe
zur Verfügung
steht. Zudem ist die Thread-ID in dem Programm-Trace integriert,
so daß die
Beziehung zwischen Anweisungen und Threads bestimmt werden kann.
-
Beispielsweise
enthält
bei einer Ausführungsform
der vorliegenden Erfindung ein Multithread-Prozessor eine Anweisungsabhol-
und -ausgabeeinheit und eine Pipeline. Die Anweisungsabhol- und
-ausgabeeinheit enthält
eine Anweisungsabholstufe, die konfiguriert ist, einen oder mehrere
Sätze von
abgeholten Bit abzuholen, die eine oder mehrere Anweisungen darstellen,
und einen Anweisungspuffer zum Speichern der Sätze von abgeholten Bit. Außerdem speichert
der Anweisungspuffer eine assoziierte Thread-ID für jeden
Satz abgeholter Bit. Die Pipeline ist an die Anweisungsabhol- und -ausgabeeinheit
gekoppelt und konfiguriert, einen Satz abgeholter Bit und die assoziierte
Thread-ID zu empfangen. Jede Pipeline-Stufe der Pipeline weist einen
Thread-ID-Speicher zum Speichern einer Thread-ID auf, die mit der
Anweisung oder dem Operanden innerhalb der Pipeline-Stufe assoziiert
ist. Der Multithread- Prozessor
kann auch eine Datenweiterleitungseinheit zum Weiterleiten von Daten
zwischen einer ersten Pipeline-Stufe
mit einer ersten Thread-ID und einer zweiten Pipeline-Stufe mit
einer zweiten Thread-ID enthalten. Wenn die erste Thread-ID gleich
der zweiten Thread-ID ist, dann ist die Datenweiterleitung zugelassen.
Die Datenweiterleitung wird jedoch verhindert, wenn die erste Thread-ID
nicht der zweiten Thread-ID entspricht.
-
Einige
Ausführungsformen
der vorliegenden Erfindung enthalten auch einen Trap-Handler, der eine
Trap-Auflösung einer
Trap verhindert, wenn der aktive Thread nicht der gleiche ist wie
der Thread, der die Trap erzeugte. Wenn der Thread, der die Trap
erzeugte, der aktive Thread wird, löst der Trap-Handler die Trap
auf.
-
Einige
Ausführungsformen
der vorliegenden Erfindung verwenden Thread-IDs bei der Erzeugung von
Programm-Traces.
Insbesondere detektiert bei einer Ausführungsform der vorliegenden
Erfindung eine Traceerzeugungseinheit die Ausgabe von Anweisungen
und erzeugt Programm-Trace-Einträge, die
die Thread-IDs des die Anweisungen enthaltenden Threads enthalten.
Bei einer weiteren Ausführungsform
der vorliegenden Erfindung detektiert die Traceerzeugungseinheit
Thread-Umschaltungen
und erzeugt einen Thread-Umschaltungsmarker
für den Programm-Trace.
Der Thread-Umschaltungsmarker kann
die Thread-ID von an der Thread-Umschaltung beteiligten Threads
enthalten.
-
Ein
eingehenderes Verständnis
der vorliegenden Erfindung ergibt sich angesichts der folgenden
Beschreibung und Zeichnungen.
-
KURZE BESCHREIBUNG DER ZEICHNUNGEN
-
1 ist
ein vereinfachtes Diagramm einer herkömmlichen Integer-Pipeline.
-
2 ist
ein vereinfachtes Diagramm einer herkömmlichen Lade-/Speicher-Pipeline.
-
3 ist
ein vereinfachtes Blockdiagramm einer Pipeline mit einer Datenweiterleitungseinheit gemäß einer
Ausführungsform
der vorliegenden Erfindung.
-
4 ist
ein vereinfachtes Blockdiagramm einer Trace-Einheit mit einer Pipeline gemäß einer Ausführungsform
der vorliegenden Erfindung.
-
AUSFÜHRLICHE BESCHREIBUNG
-
Wie
oben erläutert
vergeuden herkömmliche Multithread-Prozessoren, die
Datenweiterleitung in Pipelines unterstützen, Verarbeitungszyklen zum Leeren
des aktuellen Threads, bevor ein neuer Thread während einer Thread-Umschaltung
geladen wird, oder sie besitzen eine begrenzte Weiterleitungsfähigkeit,
zum Beispiel unterstützt
das Zyklus-für-Zyklus-Multithreading üblicherweise
nicht das Weiterleiten in irgendeine Pipelinestufe. Prozessoren
gemäß der vorliegenden
Erfindung hängen eine
Thread-ID an Anweisungen und Operanden in Pipelines an. Die Thread-ID
identifiziert den Thread, zu dem der Operand oder die Anweisung
gehört.
Die Datenweiterleitung wird zwischen Pipelinestufen verhindert,
wenn die Thread-IDs der Anweisungen oder Operanden in den Pipelinestufen
nicht übereinstimmen.
Die Thread-IDs gestatten auch Traps und eine Korrelierung mit dem
Thread, aus dem die Trap erzeugt wurde. Weiterhin kann die Thread-ID
in eine Programm-Trace integriert werden, um das Debugging und die
Entwicklung zu unterstützen.
-
3 ist
ein vereinfachtes Blockdiagramm einer Anweisungsabhol- und -ausgabeeinheit 300 mit einer
Pipeline 330. Weil sich Lade-/Speicher-Pipelines und Ausführungspipelines
bezüglich
der vorliegenden Erfindung ähnlich
verhalten, kann die Pipeline 330 sowohl Lade-/Speicher-Pipelines
als auch Ausführungspipelines
darstellen. Zudem würden
die meisten Ausführungsformen
der vorliegenden Erfindung zusätzliche,
an die Anweisungsabhol- und – ausgabeeinheit 300 gekoppelte
Pipelines enthalten. Der Klarheit und Knappheit wegen wird jedoch
nur die Pipeline 330 beschrieben. Die Anweisungsabhol- und – ausgabeeinheit 300 enthält eine
Anweisungsabholstufe (I-Stufe) 305, eine Vordecodierstufe (PD-Stufe) 310 und
einen Anweisungspuffer 320. Die Anweisungsabholstufe 305 holt
zu verarbeitende Anweisungen ab. In der Regel holt die Anweisungsabholstufe 305 einen
Satz von Bit mit einer Größe gleich
der Datenbreite des Speichersystems des Prozessors ab. Beispielsweise
würde in
64-Bit-Systemen die Anweisungsabholstufe 305 einen Satz
von 64 Bit lesen. Die Vordecodierstufe 110 führt eine
Vordecodierung durch wie etwa das Erzeugen von Operanden-Zeigern
und das Gruppieren von Anweisungen auf jedem Satz abgeholter Bit.
Der Satz von abgeholten Bit wird in einer Zeile des Anweisungspuffers 320 gespeichert.
Jeder Satz von abgeholten Bit erhält auch eine Thread-ID entsprechend
dem Thread, der den jeweiligen Satz abgeholter Bit besitzt. Wie
in 3 dargestellt, weist ein in Zeile 320_0
gespeicherter Satz von Bit eine entsprechende Thread-ID auf, die
mit dem Satz beim Thread-ID-Speicher 320_0_TID gespeichert
ist.
-
Der
Satz abgeholter Bit und die entsprechende Thread-ID werden an eine
Pipeline wie etwa Pipeline 330 ausgegeben. Im allgemeinen
wurde der Satz abgeholter Bit vordecodiert, um Operanden-Zeiger, Anweisungen
und Vordecodierinformationen zu enthalten. Im Gegensatz zu herkömmlichen
Pipelines wird die mit dem Satz abgeholter Bit assoziierte Thread-ID
an die Anweisungen und Operanden des Satzes abgeholter Bit angehängt.
-
Somit
enthält
jede Stufe der Pipeline 330 einen Thread-ID-Speicher zum Speichern
der mit dem Operanden oder der Anweisung assoziierten Thread-ID
in der Pipelinestufe. Somit enthält
die Decodierstufe 340 einen Thread-ID-Speicher TID_340. Analog
enthalten die Ausführ-Eins-Stufe 350,
die Ausführ-Zwei-Stufe 360 und
die Rückschreibstufe 370 Thread-ID-Speicher
TID_350, TID_360 beziehungsweise TID_370.
Einige Ausführungsformen
der vorliegenden Erfindung Unterstützen nur zwei aktive Threads.
Für diese
Ausführungsformen
kann es sich bei den Thread-ID-Speichern
um ein einzelnes Bit handeln. Für
andere Ausführungsformen
mit mehr aktiven Threads wären
die Thread-ID-Speicher größer als
ein einzelnes Bit.
-
Zusätzlich zu
den Pipelinestufen enthält
die Pipeline 330 auch eine erste Thread-Registerdatei 392 und
eine zweite Thread-Registerdatei 394, eine Datenweiterleitungseinheit 380 und
einen Thread-Handler 395. Der Klarheit halber sind nur zwei
Thread-Registerdateien
gezeigt. Im allgemeinen ist die Anzahl der Thread-Registerdateien
gleich der größten Anzahl
von aktiven Threads, die von dem Prozessor unterstützt werden.
Jeder aktive Thread besitzt eine entsprechende Thread-Registerdatei. Die
Anweisungen und Operanden eines Threads verwenden nur die entsprechende
Thread-Registerdatei.
-
Bei
herkömmlichen
Prozessoren, die Datenweiterleitung unterstützen, werden Operanden weitergeleitet,
wenn der in einer späteren
Pipelinestufe gespeicherte Operand in einer frühren Pipelinestufe erforderlich
ist. Bei einem Multithread-Prozessor jedoch sollte die Datenweiterleitung
nur dann erfolgen, wenn die Operanden zu dem gleichen Thread gehören. Somit
enthält
die Datenweiterleitungseinheit 380 einen Thread-ID-Komparator 383 sowie
einen Operandenkomparator 386. Der Operandenkomparator 386 bestimmt,
wann ein Operand in einer späteren Stufe
möglicherweise
in einer früheren
Stufe benötigt wird.
Der Operand wird jedoch nur dann weitergeleitet, wenn die mit dem
Operanden in der späteren
Stufe assoziierte Thread-ID gleich der mit dem Operanden in der
früheren
Stufe assoziierten Thread-ID ist.
-
Wenn
beispielsweise, wie oben erläutert,
auf die Anweisung „LD
D0, [A0]", was bedeutet,
das Datenregister D0 mit dem Wert bei der Speicheradresse A0 zu
laden, „MUL
D2, D0, D1" folgt,
was bedeutet, den Wert im Datenregister D0 mit dem Wert im Datenregister
D1 zu multiplizieren und das Ergebnis im Datenregister D2 zu speichern,
kann „MUL
D2, D0, D1" erst
ausgeführt
werden, nachdem „LD
D0, [A0]" beendet
ist. Ansonsten verwendet „MUL
D2, D0, D1" möglicherweise
einen veralteten Wert im Datenregister D0. Ein Anhalten der Pipeline
wird durch Weiterleiten des Werts von der Speicheradresse A0, in
der Ausführ-Zwei-Stufe 360 erhalten,
zu der Ausführ-Eins-Stufe 350,
die die Daten aus dem Datenregister D0 zum Verarbeiten von „MUL D2,
D0, D1" benötigt, vermieden.
Wenn jedoch die Anweisung „LD D0,
[A0]" mit einem
anderen Thread als die Anweisung „MUL D2, D0, D1" assoziiert ist,
dann sollte keine Datenweiterleitung erfolgen. Somit verwendet gemäß der vorliegenden
Erfindung die Datenweiterleitungseinheit 380 den Thread-ID-Komparator 383,
um die Thread-ID TID_360 mit der Thread-ID TID_350 zu
vergleichen. Wenn die Thread-ID TID_350 der Thread-ID TID_360 entspricht,
dann wird eine Datenweiterleitung zugelassen. Ansonsten wird die
Datenweiterleitung verhindert.
-
Somit
können
Prozessoren gemäß der vorliegenden
Erfindung mehrere Threads in einer einzelnen Pipeline gegebenenfalls
mit Datenweiterleitung unterstützen.
Deshalb erreichen Prozessoren gemäß der vorliegenden Erfindung
eine höhere
Leistung als herkömmliche Prozessoren.
-
Wie
oben beschrieben ist ein weiteres übliches Problem bei herkömmlichen
Multithread-Prozessoren das Trap-Handling.
Wenn eine Trap detektiert wird, aber nicht vor einer Thread-Umschaltung gelöst wird,
ist es wahrscheinlich, dass beim Lösen der Trap Fehler auftreten.
Somit enthält
wie in 3 dargestellt bei einer Ausführungsform der vorliegenden
Erfindung der Trap-Handler 395 ein Trap-Thread-Register 396,
das die Thread-ID des aktiven Threads speichert, wenn eine Trap
detektiert wird. Der Trap-Handler 395 löst Traps nur dann, wenn die
Thread-ID des aktiven Threads der Thread-ID des Threads entspricht,
der die Trap erzeugte, die im Trap-Thread-Register 396 gespeichert wurde.
Wenn eine Thread-Umschaltung nach der Detektion einer Trap erfolgt,
aber bevor die Trap gelöst
werden kann, würde
der Trap-Handler 395 somit die Handhabung der Trap verzögern, bis
der Thread, der die Trap erzeugte, der aktive Thread ist.
-
Ein
weiterer Vorteil bei der Verwendung der neuartigen Thread-Identifikation
der vorliegenden Erfindung besteht darin, daß das Programm-Tracing Thread-Informationen enthalten
kann. Herkömmliche eingebettete
Prozessoren enthalten eine Programm-Trace-Ausgabe zu Debugging-
und Entwicklungszwecken. Allgemein ist ein Programm-Trace eine Liste
aus Einträgen,
die die tatsächlichen
Anweisungen, die von der Anweisungsabhol- und -ausgabeeinheit abgegeben werden,
mit dem Programmzähler
immer dann verfolgt, wenn jede Anweisung ausgegeben wird. Oftmals
wird der Programm-Trace komprimiert. Eine übliche Kompressionstechnik
für Programm-Traces
besteht darin, die Anzahl der ausgegebenen Anweisungen in Tokens
umzuwandeln, zusammen mit einer Benachrichtigung über eine
etwaige Programmflußänderung,
d. h. Verzweigungen, Sprünge
oder Aufrufe. Periodisch wird (beispielsweise alle 128 oder 256
Anweisungen) eine Synchronisationsoperation durchgeführt, die
Reihen von Tokens, die die Anzahl der seit der letzten Synchronisationsoperation
ausgegebenen Anweisungen darstellt, ein Synchronisations-Token und
den aktuellen Programmzähler
in den Programm-Trace einsetzt. Ein Software-Debugger verwendet
die Tokens des Programm-Trace zum Bestimmen des Verhaltens des Prozessors
während
der Programmausführung.
-
Ein
herkömmliches
Programm-Tracing reicht jedoch für
Multithread-Prozessoren nicht aus. Insbesondere würde eine
Liste von ausgegebenen Anweisungen sogar mit einem Programmzähler nicht
ausreichen, um das Verhalten des Prozessors ohne Informationen darüber, welcher
Thread die Anweisungen enthielt, zu bestimmen.
-
Wie
in 4 dargestellt, enthalten einige Ausführungsformen
der vorliegenden Erfindung eine an die Anweisungsabhol- und -ausgabeinheit 300 und
die Pipeline 330 gekoppelte Trace-Einheit 400. Wenngleich
nicht gezeigt, wäre
die Trace-Einheit 400 auch an die anderen Pipelines im
Prozessor gekoppelt. Die Trace-Einheit 400 enthält eine
Traceerzeugungseinheit 420 und eine Tracekompressionseinheit 410.
Die Traceerzeugungseinheit 420 empfängt die Anweisung und die Thread-ID
jeder ausgegebenen Anweisung von der Anweisungsabhol- und -ausgabeeinheit 300.
Zudem überwacht
die Traceerzeugungseinheit 420 die Pipelines, um Verzweigungen, Sprünge oder
Aufrufe zu detektieren. Die Traceerzeugungseinheit 420 erzeugt
Programm-Trace-Einträge, die
zusammen den Programm-Trace bilden. Die Programm-Trace-Einträge enthalten Thread-Identifikationsinformationen
unter Verwendung der Thread-IDs von den Pipelines und der Anweisungsabhol- und -ausgabeeinheit 300.
Die Tracekompressionseinheit 410 empfängt den Programm-Trace von
der Traceerzeugungseinheit 410 und komprimiert den Programm-Trace
zu einem komprimierten Programm-Trace 410. Jede Form der Kompression
kann in der Tracekompressionseinheit 410 verwendet werden.
Die meisten Ausführungsformen
der vorliegenden Erfindung wandeln die Anweisungen wie oben erläutert in
Tokens um.
-
Die
vorliegende Erfindung enthält
mehrere Verfahren zum Einbetten einer Thread-Identifikation in den
Programm-Trace.
Beispielsweise fügen
einige Ausführungsformen
der vorliegenden Erfindung ein Thread-Identifikationsfeld für jeden
Programm-Trace-Eintrag hinzu. Das Thread-Identifikationsfeld enthält die Thread-ID
der Anweisung von der Anweisungsabhol- und -ausgabeeinheit 300. Bei
anderen Ausführungsformen
der vorliegenden Erfindung wird ein Thread-Umschaltungsmarker immer dann in den Programm-Trace
eingefügt,
wenn es zu einer Thread-Umschaltung kommt. Bei Ausführungsformen
der Trace-Kompressionseinheit 410, die den Programm-Trace
in Tokens umwandeln, wird der Thread-Umschaltungsmarker in ein Thread-Umschaltungstoken
umgewandelt.
-
Bei
einer spezifischen Ausführungsform
der vorliegenden Erfindung enthält
jeder Programm-Trace-Eintrag ein Thread-Identifikationsfeld. Die
Tracekompressionseinheit 410 wandelt den Programm-Trace
in Tokens um, die ein Thread-Identifikationsfeld enthalten. Zudem
wird immer dann eine Synchronisationsoperation durchgeführt, wenn
eine Thread-Umschaltung erfolgt. Wie oben erläutert setzt eine Synchronisationsoperation
eine Reihe von Tokens, die die Anzahl von seit der letzten Synchronisationsoperation
ausgegebenen Anweisungen darstellt, ein Synchronisationstoken und
den aktuellen Programmzähler
in den Programm-Trace ein.
-
Bei
den verschiedenen Ausführungsformen der
vorliegenden Erfindung sind neuartige Strukturen und Verfahren beschrieben
worden, um Thread-IDs zum Aufrechterhalten einer Datenkohärenz zu
verwenden und um sinnvolle Programm-Traces in Multithread-Prozessoren
zu erzeugen. Die verschiedenen Ausführungsformen der Strukturen
und Verfahren der vorliegenden Erfindung, die oben beschrieben sind,
sind nur veranschaulichend für
die Prinzipien der vorliegenden Erfindung und sollen den Schutzbereich
der Erfindung nicht auf die beschriebenen besonderen Ausführungsformen
beschränken.
Angesichts dieser Offenbarung kann beispielsweise der Fachmann andere
Anweisungsabhol- und -ausgabeeinheiten, Pipelines, Pipeline-Stufen,
Anweisungspuffer, Datenweiterleitungs-einheiten, Thread-ID-Komparatoren,
Operandenkompa-ratoren, Traceeinheiten, Traceerzeugungseinheiten,
Tracekompressionseinheiten usw. definieren und diese alternative
Merkmale verwenden, um ein Verfahren oder System gemäß den Prinzipien
der vorliegenden Erfindung zu erzeugen. Somit wird die Erfindung
nur durch die folgenden Ansprüche
beschränkt.