-
GEBIET
-
Die
vorliegenden Ausführungsformen
der Erfindung betreffen das Gebiet der Computersysteme. Insbesondere
betreffen die vorliegenden Ausführungsformen
ein Verfahren und System zum Bereitstellen eines Multi-Threading
(Mehrfädigkeit)
auf Nutzerebene.
-
ALLGEMEINER STAND DER TECHNIK
-
Multi-Threading
ist die Fähigkeit
eines Programms oder Betriebssystems, mehr als eine Abfolge von Instruktionen
gleichzeitig auszuführen.
Jede Nutzeranfrage für
ein Programm oder einen Systemdienst (wobei ein Nutzer hier auch
ein anderes Programm sein kann) wird als Thread (Faden) mit separater
Identität
verfolgt. Wenn Programme an der anfänglichen Anfrage für diesen
Thread arbeiten und von anderen Anfragen unterbrochen werden, wird
der Zustand der Arbeit für
diesen Thread verfolgt, bis die Arbeit abgeschlossen ist.
-
Zu
den Arten der Computerverarbeitung gehört Single Instruction Stream,
Single Data Stream (Einzelinstruktionsstrom, Einzeldatenstrom),
wobei es sich um den üblichen
seriellen Von-Neumann-Rechner
handelt, der einen einzelnen Instruktionsstrom enthält. Eine
zweite Verarbeitungsart ist der Prozeß Single Instruction Stream,
Multiple Data Stream (SIMD). Dieses Verarbeitungsverfahren kann
mehrere arithmetisch-logische Prozessoren und einen einzelnen Steuerprozessor
umfassen. Alle arithmetisch-logischen Prozessoren führen im
Gleichschritt Operationen an den Daten aus und werden durch den
Steuerprozessor synchronisiert. Eine dritte Art ist die Verarbeitung
Multiple Instruction Stream, Single Data Stream (MISD), die ein
Verarbeiten derselben Datenströme
durch ein lineares Array von Prozessoren umfaßt, das verschiedene Instruktionsströme ausführt. Eine
vierte Verarbeitungsart ist die Multiple Instruction Stream, Multiple
Data Stream-(MIMD)-Verarbeitung, die mehrere Prozessoren benutzt,
von denen jeder seinen eigenen Instruktionsstrom ausführt, um
einen Datenstrom zu verarbeiten, der jedem der Prozessoren zugeführt wird.
MIMD-Prozessoren können
mehrere Instruktionsverarbeitungseinheiten, mehrere Instruktionsablaufsteuerungen,
und daher mehrere Datenströme
aufweisen.
-
Das
Programmierungsmodell, das von den heutigen mehrfädigen Mikroprozessoren
angewandt wird, ist dasselbe wie bei dem traditionellen Mikroprozessor
mit gemeinsam genutztem Speicher: mehrere Threads werden so programmiert,
als ob sie auf unabhängigen
CPUs ablaufen würden.
Die Kommunikation zwischen den Threads wird durch den Hauptspeicher
durchgeführt,
und das Erzeugen/Zerstören/Scheduling
von Threads wird von dem Betriebssystem durchgeführt. Das Multi-Threading ist
nicht in einer architektonisch sichtbaren Weise bereitgestellt,
in der Programmierer direkt auf Threads zugreifen können.
-
Die
US-Patentschrift 6,463,527
B1 offenbart beispielsweise ein System zum Multi-Threading,
bei dem mehrere Thread-Steuerungseinheiten existieren. Jeder Steuerungseinheit
sind Register zugeordnet, zusätzlich
haben sie Zugriff auf globale Register.
-
KURZE BESCHREIBUNG DER FIGUREN
-
Aufgabe
der vorliegenden Erfindung ist es, ein anwendungsspezifisches verbessertes
Multi-Threading bereitzustellen.
Die Aufgabe wird gelöst
durch einen Prozessor nach Anspruch 1.
-
Die
vorliegenden Ausführungsformen
der Erfindung werden anhand der folgenden genauen Beschreibung unter
Bezugnahme auf die Figuren besser nachvollziehbar, wobei:
-
1 ein
Blockdiagramm eines beispielhaften Computersystems zeigt, das das
vorliegende Verfahren und die vorliegende Vorrichtung gemäß einer
Ausführungsform
der vorliegenden Erfindung benutzt;
-
2 einen
beispielhaften Chip-Multiprozessor zeigt;
-
3 einen
beispielhaften simultanen Multi-Threadprozessor zeigt;
-
4 einen
beispielhaften asymmetrischen Multiprozessor g zeigt;
-
5 eine
beispielhafte Ausführungsumgebung
zum Bereitstellen eines Multi-Threadings auf Nutzerebene gemäß einer
Ausführungsform
der vorliegenden Erfindung zeigt;
-
6 ein
beispielhaftes Verhältnis
zwischen Shreds und gemeinsamen Speicher-Threads gemäß einer
Ausführungsform
der vorliegenden Erfindung zeigt; und
-
7 ein
Ablaufdiagramm eines beispielhaften Prozesses des Multi-Threadings
auf Nutzerebene gemäß einer
Ausführungsform
der vorliegenden Erfindung zeigt.
-
DETAILLIERTE BESCHREIBUNG
-
Es
werden ein Verfahren und ein System zum Bereitstellen eines Multi-Threadings
auf Nutzerebene offenbart. Das Verfahren gemäß den vorliegenden Techniken
umfaßt
das Empfangen von Programmierinstruktionen, um einen oder mehrere
gemeinsame Ressourcen-Threads
(Shared Resource Threads – Shreds) über eine
Instruktionssatz-Architektur (ISA) auszuführen. Ein oder mehrere Instruktionszeiger
werden über
die ISA konfiguriert; und der oder die Shreds werden mit einem Mikroprozessor
simultan ausgeführt,
wobei der Mikroprozessor Ablaufsteuerungen für mehrere Instruktionen enthält.
-
In
der folgenden Beschreibung wird zu Erläuterungszwecken eine spezifische
Nomenklatur verwendet. Allerdings werden Fachleute verstehen, daß diese
spezifischen Details nicht erforderlich sind. Einige Abschnitt der
folgenden genauen Beschreibungen sind in Form von Algorithmen und
symbolischen Darstellungen von Operationen an Datenbits in einem
Computerspeicher dargestellt. Diese algorithmischen Beschreibungen und
Darstellungen sind Mittel, die von Fachleuten auf dem Gebiet der
Datenverarbeitung benutzt werden, um anderen Fachleuten auf möglichst
effektive Weise den Kern ihrer Arbeit zu vermitteln. Ein Algorithmus
ist hier im allgemeinen als eine in sich stimmige Abfolge von Operationen
zu verstehen, die zu einem gewünschten Ergebnis
führt.
Diese Operationen sind solche, die eine physikalische Manipulation
physikalischer Größen erforderlich
machen. Normalerweise, aber nicht unbedingt, nehmen diese Größen die
Form elektrischer oder magnetischer Signale an, die gespeichert, übertragen,
kombiniert, verglichen, oder in anderer Weise manipuliert werden
können.
Bisweilen erwies es sich hauptsächlich
aus Gründen
der üblichen
Verwendungsweise als praktisch, diese Signale als Bits, Werte, Elemente,
Symbole, Zeichen, Ausdrücke,
Zahlen oder ähnliches
zu bezeichnen.
-
Es
sollte beachtet werden, daß alle
diese und ähnliche
Begriffe mit den geeigneten physikalischen Größen in Verbindung zu bringen
sind, und lediglich praktische Bezeichnungen darstellen, die auf
diese Größen angewandt
werden. Sofern nicht in der Beschreibung ausdrücklich anders angegeben, versteht
es sich, daß in
der gesamten Beschreibung Erörterungen,
die Begriffe wie „Verarbeiten” oder „Berechnen” oder „Errechnen” oder „Bestimmen” oder „Anzeigen” oder ähnliches
benutzen, sich auf die Aktivität
und die Prozesse eines Computersystems oder einer ähnlichen
elektronischen Vorrichtung beziehen, die Daten manipuliert und umwandelt,
welche in den Registern und Speichern oder anderen derartigen Speicher-, Übertragungs-
und Anzeigevorrichtungen des Computersystems als physikalische (elektronische)
Größen wiedergegeben
sind.
-
Die
Ausführungsformen
der bereitgestellten Erfindung betreffen auch eine Vorrichtung zum
Durchführen
der vorgestellten Operationen. Diese Vorrichtung kann speziell für die vorgesehenen
Zwecke konstruiert sein, oder einen allgemein einsetzbaren Computer
umfassen, der von einem Computerprogramm, das in dem Computer gespeichert
ist, selektiv aktiviert oder neu konfiguriert wird. Ein solches
Computerprogramm kann in einem computerlesbaren Speichermedium gespeichert
sein, wie z. B., aber ohne Beschränkung auf, jede Art von Diskette,
einschließlich
Magnetplattenspeicher-Disketten, optischen Disketten, CD-ROMs und
magneto-optischen
Disketten, Lesespeichern (ROMs), Schreib-Lesespeichern (RAMs), EPROMs,
EEPROMs, magnetischen oder optischen Karten, oder jedes Medientyps,
der zum Speichern elektronischer Instruktionen geeignet ist, und
der jeweils an einen Computersystembus gekoppelt ist.
-
Die
hier vorgestellten Algorithmen und Darstellungen stehen nicht inhärent in
Bezug zu einem bestimmten Computer oder einer bestimmten Vorrichtung.
Verschiedene allgemein einsetzbare Systeme können mit Programmen gemäß den hier
dargestellten Lehren benutzt werden, oder es kann sich als praktisch
erweisen, eine stärker
spezialisierte Vorrichtung zu konstruieren, um das benötigte Verfahren
durchzuführen.
Die erforderliche Struktur für
verschiedene dieser Systeme wird aus der nachfolgenden Beschreibung
hervorgehen. Außerdem
ist eine Ausführungsform
der vorliegenden Erfindung nicht unter Bezugnahme auf eine bestimmte
Programmiersprache beschrieben. Man wird verstehen, daß verschiedene
Programmiersprachen benutzt werden können, um die Lehren der Ausführungsformen
der Erfindungen zu implementieren, wie sie hier beschrieben sind.
-
Ein „Nutzer”, wie in
der gesamten Beschreibung benutzt, bezeichnet Software auf Nutzerebene,
wie z. B. Anwendungsprogramme, nichtprivilegierten Code und ähnliche
Software. Software der Nutzerebene ist von einem Betriebssystem
oder ähnlicher
privilegierter Software zu unterscheiden. Gemäß einer Ausführungsform
der vorliegenden Erfindung gilt die folgende Beschreibung für MIMD-Prozessoren,
wie oben beschrieben.
-
1 zeigt
ein Blockdiagramm eines beispielhaften Computersystems 100,
welches das vorliegende Verfahren und die vorliegende Vorrichtung
gemäß einer
Ausführungsform
der vorliegenden Erfindung benutzt. Das Computersystem enthält einen
Prozessor 105. Ein Chipsatz 110 stellt Speicher-
und E/A-Funktionen für das
System 100 bereit. Insbesondere enthält der Chipsatz 110 einen
GMCH (Graphics and Memory Controller Hub) 115. Der GMCH
dient als eine Host-Steuerung, die mit Prozessor 105 kommuniziert,
und außerdem
als eine Steuerung für
den Hauptspeicher 120. Der Prozessor 105 erlaubt
die Erweiterung des Multi-Threading auf eine Nutzerebene, gemäß einer
Ausführungsform
der vorliegenden Erfindung. Der GMCH 115 stellt außerdem eine
Schnittstelle zur einer AGP-(Accelerated Graphics Port)-Steuerung 125 bereit,
die daran gekoppelt ist. Der Chipsatz 110 weist außerdem einen
E/A-Steuerungs-Hub (I/O Controller Hub – ICH) 135 auf, der
verschiedene E/A-Funktionen ausführt.
Der ICH 135 ist an einen Systemverwaltungsbus (SM-Bus)
gekoppelt.
-
Der
ICH 135 ist an einen PCI-(Peripheral Component Interconnect)-Bus 155 gekoppelt.
Eine Super-E/A-(„SID”)-Steuerung 170 ist
an ICH 135 gekoppelt, um Verbindungsfähigkeit für Eingabevorrichtungen wie
z. B. eine Tastatur und eine Maus 175 bereitzustellen.
Ein allgemein verwendbarer E/A-(GPIO)-Bus 195 ist an den
ICH 135 gekoppelt. USB-Anschlüsse 200 sind an den
ICH 135 gekoppelt, wie dargestellt. USB-Vorrichtungen wie
Drucker, Scanner, Joysticks usw. können an diesem Bus der Systemkonfigurierung
hinzugefügt werden.
Ein IDE-(Integrated Drive Electronics)-Bus 205 ist an den
ICH 135 gekoppelt, um die IDE-Treiber 210 mit
dem Computersystem zu verbinden. Logisch erscheint der ICH 135 als
mehrere PCI-Vorrichtungen in einer einzelnen physikalischen Komponente.
-
Im
Prozessor 105 ist eine Instruktionssatz-Architektur enthalten.
Eine Instruktionssatz-Architektur (ISA)
ist ein abstraktes Modell eines Mikroprozessors, wie z. B. Prozessor 105,
das aus Zustandelementen (Registern) und Instruktionen zusammengesetzt
ist, die diese Zustandelemente bearbeiten. Die Instruktionssatz-Architektur
dient als eine Grenze zwischen Software und Hardware, indem sie
eine abstrakte Spezifikation des Verhaltens des Mikroprozessors
sowohl an den Programmierer als auch an den Designer des Mikroprozessors
bereitstellt.
-
Fortschritte
im Zusammenhang mit der Anzahl von Transistoren, die auf einem Siliziumchip
verfügbar sind,
haben die Einführung
des Multi-Threading in Mehrzweck-Mikroprozessoren ermöglicht.
Multi-Threading kann auf zwei verschiedene Weisen implementiert
werden: Als Chip-Multiprozessor (CMP) und als simultaner Multi-Threadprozessor
(SMT), von denen beide als Prozessor 105 benutzt werden
können.
-
2 zeigt
einen beispielhaften Chip-Multiprozessor als Ausführungsbeispiel.
Bei einem Chip-Multiprozessor
wie z. B. Prozessor 200 sind mehrere CPU-Kerne 210 bis 213 auf
einem einzigen Siliziumchip 200 integriert. Jeder der CPU-Kerne 210 bis 213 ist
dazu in der Lage, einen unabhängigen
Ausführungsthread 220 bis 223 auszuführen, obwohl
einige Ressourcen (wie z. B. Caches) von mehr als einem CPU-Kern 210 bis 213 zugleich
benutzt werden können.
-
3 zeigt
einen beispielhaften simultanen Multi-Threadprozessor 300 gemäß einer
Ausführungsform
der Erfindung. Der Prozessor 105 kann ein simultaner Multi-Threadprozessor
wie z. B. Prozessor 300 sein. Bei einem simultanen Multi-Threadprozessor 300 ist
ein einzelner CPU-Kern 310 dazu in der Lage, mehrere Ausführungsthreads
auszuführen.
Der CPU-Kern 310 erscheint für Software als zwei oder mehr
Prozessoren, indem CPU-Ressourcen von extrem feiner Granularität gemeinsam
genutzt werden (wobei oft auf einer Takt-für-Takt-Basis bestimmt wird,
welcher Thread mit einer jeweiligen Ressource verarbeitet wird).
-
4 zeigt
einen beispielhaften asymmetrischen Multiprozessor 400 als
Ausführungsbeispiel.
Der Prozessor 105 kann ein asymmetrischer Prozessor wie
z. B. Prozessor 400 sein. Es ist möglich, einen Chip-Multiprozessor 400 zu
konstruieren, in dem die CPU-Kerne 410 bis 427 eine
unterschiedliche Mikroarchitektur, aber dieselbe ISA aufweisen.
Beispielsweise kann eine kleine Zahl von Hochleistungs-CPU-Kernen 410 bis 411 in
eine große
Zahl von Niedrigstrom-CPU-Kernen 420 bis 427 integriert
sein. Diese Art der Auslegung kann einen hohen Aggregatdurchsatz
sowie eine hohe Skalarleistung erzielen. Die zwei Arten von CPU-Kernen
können
für die
Software entweder als übliche
gemeinsame Speicher-Threads, oder als die Shreds, oder als eine
Kombination beider erscheinen. Die Instruktionssatz-Architektur
(ISA) ist ein abstraktes Modell eines Mikroprozessors, wie z. B.
Prozessor 105, der aus Zustandelementen (Registern) und
Instruktionen zusammengesetzt ist, die diese Zustandelemente bearbeiten.
Die ISA dient als eine Grenze zwischen Software und Hardware, indem
sie eine abstrakte Spezifikation des Verhaltens des Mikroprozessors
sowohl an den Programmierer als auch an den Designer des Mikroprozessors
bereitstellt. Das vorliegende Programmierungsmodell ermöglicht es
denn Anwendungsprogramm, mehrere asymmetrische CPU-Kerne direkt
zu steuern.
-
Gemeinsames Speicher-Programmierungsmodell
-
Multi-Threadprozessoren
des Stands der Technik verwenden dasselbe Programmiermodell wie
gemeinsame Speicher-Multiprozessorsysteme des Stands der Technik.
Das Programmiermodell ist wie folgt aufgebaut. Ein Mikroprozessor
stellt mehrere Ausführungsthreads
an das Betriebssystem bereit. Das Betriebssystem benutzt diese Threads,
um mehrere Anwendungen („Prozesse”) gleichzeitig
zu betreiben, und/oder um mehrere Threads von einer einzigen Anwendung
(„mehrfädig”) gleichzeitig
zu betreiben. In beiden Fällen
erscheinen die Threads für
die Software als unabhängige
CPUs. Der Hauptspeicher wird von allen Threads gemeinsam genutzt,
und die Kommunikation zwischen Threads erfolgt über den Hauptspeicher. Hardwareressourcen
in der CPU können
ebenfalls gemeinsam genutzt werden, aber das gemeinsame Nutzen ist
vor der Software durch die Mikroarchitektur verborgen.
-
Obwohl
das traditionelle Programmiermodell für gemeinsame Speicher-Multiprozessoren
allgemein von vielen Betriebssystemen und Anwendungsprogrammen verstanden
und unterstützt
wird, weist das Modell eine Reihe von Nachteilen auf. Diese sind:
- 1) Die Kommunikation zwischen den Threads erfolgt über den
Hauptspeicher, und ist deshalb extrem langsam. Cachen kann einen
Teil der Wartezeit reduzieren, doch die Cache-Zeile muß von einem
CPU-Kern an den nächsten
weitergereicht werden, um die gemeinsame Nutzung zu erleichtern.
- 2) Eine Synchronisation zwischen Threads wird mit Hilfe speicherbasierter
Semaphore durchgeführt,
und ist deshalb extrem langsam.
- 3) Das Erzeugen, Zerstören,
Aussetzen und Wiederaufnehmen von Threads erfordert das Eingreifen
des Betriebssystems, und ist deshalb extrem langsam.
- 4) Ein Mikroprozessorhersteller ist nicht dazu in der Lage,
das effektivste Multi-Threading bereitzustellen, da Verbesserungen
des CPU-Multi-Threadings durch die oben beschriebenen Speicherwartezeiten
und Betriebssystem-Wartezeiten verwässert werden.
-
Multi-Threading-Architekturerweiterungen
-
Aus
den oben genannten Gründen
im Zusammenhang mit Systemen des Stands der Technik erweitern das
vorliegende Verfahren und System die Prozessorarchitekturen durch
Multi-Thread-Architekturerweiterungen,
damit sie architektonisch sichtbares Multi-Threading aufweisen.
-
Mehrere
simultane Ausführungsthreads,
mehrere Instruktionszeiger, und mehrere Kopien von bestimmten Anwendungszuständen (Registern)
in einem einzelnen Verarbeitungselement werden bereitgestellt. Die
Ausführungsthreads
sind von existierenden gemeinsamen SpeicherThreads zu unterscheiden,
und werden als Shreds, oder gemeinsame Ressourcen-Threads (Shared
Resource Threads), bezeichnet.
-
Die
vorliegende Multi-Threading-Architekturerweiterungen (von denen
ein Beispiel im folgenden als „MAX” bezeichnet
wird) würden
die existierenden Fähigkeiten
der Architektur umfassen, und außerdem mehrere simultane Shreds,
die jeweils einen eigenen Instruktionszeiger aufweisen, Mehrzweckregister,
FP-Register, Branch-Register, Prädikatregister,
und bestimmte Anwendungsregister unterstützen. Nichtprivilegierte Instruktionen
werden erzeugt, um Shreds zu erzeugen und zu zerstören. Die
Kommunikation zwischen Shreds erfolgt über gemeinsam genutzte Register
neben gemeinsam genutztem Speicher (Shared Memory). Die Notwendigkeit
von Semaphoren würde
reduziert, da die vorliegenden Multi-Thread-Architekturerweiterungen
einen atomaren Zugriff auf gemeinsam genutzte Register gewährleisten
würden.
Außerdem
können
die vorliegenden Multi-Thread-Architekturerweiterungen mit 32-Bit-Architekturen
benutzt werden, wie z. B. der 32-Bit-Architektur von Intel®,
oder 64-Bit-Architekturen, wie z. B. der 64-Bit-Architektur von
Intel®,
oder sogar mit 16-Bit-Architekturen.
-
Ein
Vergleich zwischen dem üblichen
Thread eines gemeinsamen Speicher-Multiprozessors und einem Shred
ist in der folgenden Tabelle gezeigt, gemäß einer Ausführungsform
der vorliegenden Erfindung.
Operation | Thread
eines gemeinsamen Speicher-Multiprozessors | Multi-Thread-Architektur-Erweitungsshred |
Erzeugung,
Zerstörung | Aufruf
durch Betriebssystem | Nichtprivilegierte
Instruktion |
Kommunikation | Gemeinsamer
Speicher | Gemeinsame
Register und gemeinsamer Speicher |
Systemzustand | Eigener
Systemzustand für
jeden Thread | Gemeinsamer
Systemzustand für alle
Shreds |
Tabelle
1
-
Es
ist zu beachten, daß die
vorliegenden Multi-Thread-Architekturerweiterungen sich fundamental
von Architekturerweiterungen des Stands der Technik unterscheiden.
Während
Architekturerweiterungen des Stands der Technik mehr Instruktionen
und mehr Register(zustände)
vorsehen, sieht die Multi-Thread-Architekturerweiterung mehr Ausführungseinheiten
vor.
-
Anwendungs- und Systemzustand
-
Ein
für den
Programmierer sichtbarer CPU-Zustand kann in zwei Kategorien unterteilt
werden: Anwendungszustand und Systemzustand. Der Anwendungszustand
wird sowohl von dem Anwendungsprogramm als auch dem Betriebssystem
benutzt und gesteuert, während
der Systemzustand nur von dem Betriebssystem gesteuert wird.
-
5 zeigt
eine beispielhafte Ausführungsumgebung
zum Bereitstellen eines Multi-Threadings auf Nutzerebene, gemäß einer
Ausführungsform
der vorliegenden Erfindung. Die Ausführungsumgebung
600 enthält die Register,
deren Anwendungszustand in der folgenden Tabelle zusammengefaßt ist:
31-Bit-Architektur-Anwendungszustand | Name | Breite |
Mehrzweckregister 605
| FAX,
EBX, ECX, EDX, FBP, ESI, EDI, ESP | 32-Bits |
Gleitkommaregister 625
| ST0–7 | 80-Bits |
Segmentregister 610
| CS,
DS, ES, FS, GS, SS | 16-Bits |
Flag-Register 615
| EFLAGS | 32-Bits,
bestimmte Bits sind Anwendung |
Instruktionszeiger 620
| EIP | 32-Bits |
FP-Steuerung und Zustandregister 626–631
| CW 626, | 16-Bits, |
SW 627, | 16-Bits, |
TW 628
| 16-Bits, |
FP-Opcode 629, | 11-Bits, |
Instruktionszeiger 630, | 46-Bits, |
Operandenzeiger 631
| 48-Bits |
MMX-Register 635
| MM0–7 | 64-Bits,
Aliased an ST0–7 |
SSE-Register 640
| XMM0–7 | 128-Bits |
MXCSR-Register 645
| MXCSR | 32-Bits |
Tabelle
2
-
Die
Nutzerebenen-Multi-Threadregister 650 bis 655 sollen
im folgenden genauer beschrieben werden.
-
Der
32-Bit-Architektursystemzustand ist im folgenden zusammengefaßt.
32-Bit-Architektursystemzustand | Nummer | Breite |
Steuerregister 626
| CR0–CR4 | 32-Bits |
Flag-Register 615
| Subset
EFLAGS | 32-Bits,
Subset |
Speicherverwaltungsregister | GDTR,
IDTR | 48-Bits |
Lokaldeskriptortabellen-Register, Task-Register | LDTR,
TR | 16-Bits |
Debug-Register | DR0–DR7 | 32-Bits |
Modellspezifische
Register 650
| MSR0–MSRN | 64-Bits
Darunter
Register für
Zeitstempelzähler,
APIC, Maschinenprüfung,
Memory Type Range Register, Leistungsüberwachung |
Gemeinsame
Register | SH07–SH7 | 32-Bits |
Shred-Steuerregister | SC0–SC4 | 32-Bits |
Tabelle
3
-
Für jeden
Shred ist der Anwendungszustand in zwei Kategorien unterteilt: Anwendungszustand
pro Shred und gemeinsamer Anwendungszustand. Das hier beschriebene
MAX-Programmierungsmodell
stellt einen eindeutigen Fall des Anwendungszustands pro Shred bereit,
während
der gemeinsame Anwendungszustand von mehreren Shreds genutzt wird.
Es gibt nur eine Kopie des Systemzustands, und alle Shreds, die einem
jeweiligen Thread zugeordnet sind, nutzen denselben Systemzustand.
Eine annähernde
Teilung von Anwendung und Zustand ist in der folgenden Tabelle dargestellt:
Zustand | Typ |
Mehrzweckregister
(programmierbares Subset)
Gleitkommaregister (programmierbares
Subset)
SSE-Register (programmierbares Subset)
Instruktionszeiger
Flaggen
(Anwendungssubset) | Pro-Shred-Privatzustand |
Mehrzweckregister
(programmierbares Subset)
Gleitkommaregister (programmierbares
Subset)
SSE-Register (programmierbares Subset)
Gemeinsame
Register (neu)
Speicherverwaltungsregister
Adreßübersetzungen
(TLBs)
Aktuelle Privilegebene
Steuerregister | Gemeinsam
von mehreren Shreds benutzt, privat für jeden Thread |
Hauptspeicher | Gemeinsam
von mehreren Threads benutzt |
Tabelle
4
-
Die
vorliegende Multi-Thread-Architekturerweiterung bietet ein programmierbares
gemeinsames Nutzen oder einen Privatzustand für fast jeden Anwendungszustand,
sodaß Software
die beste Unterteilung auswählen
kann. Die Programmierung erfolgt mit einem Bit-Vektor, sodaß einzelne
Register als entweder gemeinsam oder privat ausgewählt werden
können.
Ein Hardware-Umbenenner
kann Register entweder aus einer gemeinsamen Basis oder einer privaten
Basis zuweisen, wie von dem Bit-Vektor vorgegeben.
-
Die
Gesamtspeicheranforderungen von MAX sind geringer als die von simultanen
Multi-Threadprozessoren
und Chip-Multiprozessoren des Stands der Technik. Bei MAX wird nur
der Privatanwendungszustand pro Shred repliziert, während bei
simultanen Multi-Threadprozessoren und Chip-Multiprozessoren, welche
das traditionelle gemeinsame Speicher-Multiprozessor-Programmiermodell
implementieren, der gesamte Anwendungs- und Systemzustand repliziert
werden muß.
-
Shred/Faden-Hierarchie
-
Jeder
gemeinsame Speicher-Thread ist aus einer Vielzahl von Shreds zusammengesetzt.
Die Shreds und gemeinsamen Speicher-Threads bilden eine Zweiebenen-Hierarchie.
In einer alternativen Ausführungsform
kann eine Dreiebenen-Hierarchie aus Cluster von gemeinsamen Speicher-MAX-Prozessoren
aufgebaut werden. Die Cluster kommunizieren mit Hilfe von Message
Passing. Das Betriebssystem übernimmt
das Thread-Scheduling, während
das Anwendungsprogramm das Shred-Scheduling übernimmt. Die Shreds sind nicht
gleichförmig,
und zwar in dem Sinn, daß jeweilige
Shreds andere Shreds als entweder lokal oder entfernt betrachten.
Der Anwendungszustand pro Shred wird für jeden Shred repliziert. Der
gemeinsame Anwendungs- und Systemzustand ist allen lokalen Shreds
gemein, und wird für
jeden gemeinsamen Speicher-Thread repliziert. Der Speicherzustand
verfügt über nur
eine Kopie.
-
6 zeigt
ein beispielhaftes Verhältnis
zwischen Shreds und gemeinsamen Speicher-Threads gemäß einer
Ausführungsform
der vorliegenden Erfindung. Pro-Shred-Anwendungszustand 510 wird
für jeden Shred
repliziert. Der gemeinsame Anwendungs- und Systemzustand 520 ist
den lokalen Shreds gemein, und wird für jeden gemeinsamen Speicher-Thread
repliziert. Der Speicherzustand 530 verfügt über nur
eine Kopie.
-
Da
der Systemzustand 520 mehreren Shreds in dem MAX-Programmierungsmodell
gemeinsam ist, gehören
die Shreds zu demselben Prozeß.
Die vorliegenden Multi-Thread-Architekturerweiterungen sind dafür vorgesehen,
von Multi-Threadanwendungen, Bibliotheken und virtuellen Maschinen
benutzt zu werden. Das MAX-Programmierungsmodell verleiht diesem
Typ Software ein nie dagewesenes Ausmaß an Kontrolle über ihre
Shreds, und ein Leistungspotential, das mit dem oben erörterten
gemeinsamen Speicher-Multiprozessor-Programmierungsmodell nicht erreichbar
ist.
-
Zwischen
den Shreds ist keine Schutzprüfung
vonnöten,
da sie alle auf derselben Privilegebene arbeiten und dieselbe Adreßübersetzung
nutzen. So kann der traditionelle Schutzmechanismus bei der Kommunikation
zwischen den Shreds vermieden werden.
-
Aufgrund
des gemeinsamen Systemzustands kann das MAX-Programmierungsmodell
benutzt werden, um verschiedene Prozesse auf demselben Thread ablaufen
zu lassen. Aus diesem Grund existieren die Programmierungsmodelle
MAX und gemeinsamer Speicher nebeneinander in demselben System.
-
Da
eine jeweilige CPU nur eine endliche Anzahl von physikalischen Shreds
bietet, virtualisiert die Software die Anzahl verfügbarer Shreds
in ähnlicher
Weise wie bei der Virtualisierung von Hardware-Threads. Die Virtualisierung
führt zu
einer endlichen Zahl von gegenwärtig
ablaufenden physikalischen Shreds, zusammen mit einer potentiell
unbegrenzten Zahl virtueller Shreds.
-
Systemaufrufe
-
Betriebssystemaufrufe
können
in der üblichen
Weise verarbeitet werden, indem die Steuerung von dem Anwendungsprogramm
auf das Betriebssystem übertragen
wird, und ein Kontextwechsel durchgeführt wird. Mit der MAX-Architektur
besteht ein Hauptunterschied darin, daß das Aufrufen des Betriebssystems
an einem Shred die Ausführung
aller Shreds aussetzt, die einem jeweiligen Thread zugeordnet sind.
Das Betriebssystem ist dafür
verantwortlich, den Zustand aller Shreds zu sichern und wiederherzustellen,
die zu demselben Thread gehören.
-
Aufgrund
des zusätzlichen
Zustands nimmt der Kontextwechsel-Overhead zu. Der Kontextwechsel-Speicherabdruck
wächst
proportional zu der Anzahl der Shreds. Allerdings nimmt die Kontextwechselzeit nicht
stark zu, da jeder Shred seinen Zustand parallel zu anderen Shreds
sichern/wiederherstellen kann. Der Kontextwechselmechanismus erlaubt
ein paralleles Sichern/Wiederherstellen des Speichers mit Hilfe
von mehreren Ablaufsteuerungen. Das Betriebssystem selbst benutzt
mehrere Shreds.
-
Da
die Kosten zum Aufrufen des Betriebssystems zunehmen, sollen bestimmte
Funktionen, die von dem Betriebssystem ausgeführt werden, auf das Anwendungsprogramm übertragen
werden. Zu diesen Funktionen zählen
die Thread-Verwaltung und die Verarbeitung bestimmter Ausnahmen
und Interrupts.
-
Eine
alternative Ausführungsform
zum Durchführen
von Systemaufrufen basiert auf der Beobachtung, daß Threads
billig werden, Kontextwechsel hingegen teuer. In dieser Ausführungsform
läuft ein
Thread ausschließlich
im Betriebssystem ab, und ein zweiter Thread läuft ausschließlich im
Anwendungsprogramm ab. Wenn der Anwendungsprogramm-Shred einen Systemaufruf
durchführt,
sendet er eine Nachricht an einen Betriebssystem-Shred (über gemeinsamen
Speicher) und wartet auf eine Antwortnachricht. Auf diese Weise
ersetzt der Nachrichtenweiterleitungs-(Message Passing) und Wartemechanismus
den üblichen
Steuerungsübertragungs-
und Kontextwechselmechanismus. Für
keinen der Threads ist eine Änderung
der Adreßübersetzung
nötig.
Der Vorteil ist, daß eine
Nachricht, die von einem Shred an das Betriebssystem gesendet wird,
andere lokale Shreds nicht stört.
-
Ausnahmen
-
In
Architekturen des Stands der Technik setzen Ausnahmen die Ausführung des
Anwendungsprogramms aus, und rufen ein Ausnahmensteuerungsprogramm
des Betriebssystems auf. Unter dem MAX-Programmierungsmodell ist
dieses Verhalten unerwünscht,
da das Aussetzen eines Shreds zum Aufrufen des Betriebssystems dazu
führt,
daß alle
Shreds (die einem bestimmten Thread zugeordnet sind) ebenfalls ausgesetzt
werden.
-
Um
dieses Problem zu lösen,
führen
wir einen neuen Ausnahmemechanismus auf Nutzerebene ein, der dem
Anwendungsprogramm die erste Gelegenheit bietet, viele Typen von
Ausnahmen zu bedienen. Der Ausnahmemechanismus auf Nutzerebene basiert
auf der Beobachtung, daß einige
wenige existierende Ausnahmetypen letztlich von der Anwendung selbst
bedient werden.
-
Für den Ausnahmemechanismus
auf Nutzerebene wird dazwischen unterschieden, wie eine Ausnahme
gemeldet wird, im Gegensatz dazu, wie sie bedient wird. Ausnahmen
können
wie folgt in drei Kategorien unterteilt werden.
- 1.
Ausnahmen werden dem Anwendungsprogramm mitgeteilt und von dem Anwendungsprogramm
bedient. Beispielsweise wird eine „Divide by Zero”-(Teilen
durch Null)-Ausnahme
an die Anwendung gemeldet, welche die Ausnahme verursacht hat, und
auch von Anwendung bedient. Eine Beteiligung des Betriebssystems
ist weder nötig
noch wünschenswert.
- 2. Ausnahmen, die dem Anwendungsprogramm gemeldet werden, welches
dann für
die Bedienung das Betriebssystem aufrufen muß. Ein Seitenfehler, der von
einer Anwendung verursacht wird, kann der Anwendung gemeldet werden,
aber das Anwendungsprogramm muß das
Betriebssystem aufrufen, um die Seite zu vertauschen.
- 3. Ausnahmen, die an das Betriebssystem gemeldet und von diesem
bedient werden müssen.
Aus Sicherheitsgründen
müssen
Hardware-Interrupts an das Betriebssystem gemeldet werden. Systemaufrufe
(Software-Interrupts) müssen
selbstverständlich
an das Betriebssystem gemeldet werden.
-
Die
folgende Tabelle zeigt die Ausnahmen in jeder der drei Kategorien.
Die Ausnahmentypen „Load-Ausnahme
bei Cache-Miss” und „Feinkörniger Taktgeber” sind als
Ausnahmetypen für
eine Ausführungsform
der vorliegenden Erfindung vorgesehen.
Ausnahmetyp | Gemeldet
an | Bedient
durch |
Teilung
durch Null, Überlauf,
Bound, FP-Ausnahme | Anwendung | Anwendung |
Ausrichtungsprüfung | Anwendung | Anwendung |
Ungültiger Opcode | Anwendung | Anwendung |
Load-Ausnahme
bei Cache-Miss | Anwendung | Anwendung |
Feinkörniger Taktgeber | Anwendung | Anwendung |
Fehler
im Stacksegment | Anwendung | System |
Allgemeiner
Schutz | Anwendung | System |
Seitenfehler | Anwendung | System |
Doppelfehler | Anwendung | System |
Gerät nicht
verfügbar | Anwendung | System |
Hardware-Interrupt | System | System |
Nicht
maskierbarer Interrupt | System | System |
Software-Interrupt
(INT n) | System | System |
Tabelle
5
-
Ausnahmen,
die dem Anwendungsprogramm gemeldet werden, werden selektiv in der
Anwendung verarbeitet, oder zum Verarbeiten an das Betriebssystem
weitergeleitet. Im letzteren Fall führt das Anwendungsprogramm
einen Systemaufruf durch, um explizit einen Dienst von dem Betriebssystem
in Reaktion auf die Ausnahme (wie z. B. einen Seitenfehler) anzufordern.
Dies steht im Gegensatz zu dem traditionellen Ansatz, daß das Betriebssystem
solche Dienste implizit für
die Anwendung durchführt.
Um geschachtelte Ausnahmen zu verhindern, sind bestimmte Bedingungen
vorgesehen, um sicherzustellen, daß der Anwendungscode, der Ausnahmen
an das Betriebssystem weiterleitet, nicht selbst zusätzliche
Ausnahmen erzeugt. Der Nutzerebene-Ausnahmemechanismus speichert
eine minimale Anzahl von CPU-Registern in einem Schattenregistersatz,
und die Prozessorvektoren an einem bestimmten Ort.
-
Virtuelle Maschinen
-
Virtuelle
Maschinen und die vorliegenden Ausführungsformen der Multi-Thread-Architekturerweiterungen
belegen einander mit Beschränkungen,
da virtuelle Maschinen immer dann Ausnahmen auslösen, wenn Software versucht,
auf eine Ressource zuzugreifen, die virtualisiert wird, und die
Verarbeitung von Ausnahmen signifikante Auswirkungen auf die Leistung
von Shreds ausübt.
-
In
einer virtuellen Maschine lösen
die Ausführung
von privilegierten Instruktionen oder der Zugriff auf einen privilegierten
Prozessorzustand eine Ausnahme aus. Die Ausnahme muß dem Virtuelle-Maschinen-Monitor
gemeldet (und von diesem bedient) werden. Bei MAX veranlassen Ausnahmen,
die von dem Betriebssystem (und dem Virtuelle-Maschinen-Monitor)
bedient werden, dazu, daß alle
Shreds, die einem jeweiligen Thread zugeordnet sind, ausgesetzt
werden. Der Virtuelle-Maschinen-Monitor versteht die Anwesenheit
von mehreren Shreds. Die virtuelle Maschinenarchitektur minimiert
die Anzahl von Ausnahmen, die für
nichtprivilegierte Instruktionen und Prozessorressourcen ausgelöst werden.
-
Verklemmung
-
Das
Verhindern von Verklemmungen ist in der MAX-Architektur kompliziert,
da Shreds von anderen lokalen Shreds ausgesetzt werden können. Die
Anwendungssoftware stellt sicher, daß keine Verklemmung auftritt,
wenn ein Shred eine vom Betriebssystem bediente Ausnahme oder einen
Systemaufruf auslöst,
was dazu führt,
daß alle
lokalen Shreds ausgesetzt werden.
-
Lokale
Kommunikation und Synchronisation (zwischen Shreds) ist von entfernter
Kommunikation und Synchronisation (zwischen Threads) zu unterscheiden.
Lokale Kommunikation erfolgt entweder mit Hilfe gemeinsamer Register 655 (dargestellt
in 5) oder gemeinsamem Speicher. Entfernte Kommunikation
erfolgt mit Hilfe von gemeinsamem Speicher. Eine lokale Datensynchronisation
erfolgt mit Hilfe atomarer Registeraktualisierungen, Registersemaphore,
oder Speichersemaphore. Eine entfernte Datensynchronisation erfolgt
mit Hilfe von Speichersemaphoren.
-
Sowohl
lokale als auch entfernte Shred-Steuerung (Erzeugung, Zerstörung) wird
mit Hilfe der MAX-Instruktionen durchgeführt. Die Shred-Steuerung ruft
das Betriebssystem nicht für
wait () oder yield () auf, da dies den unbeabsichtigten Effekt nach
sich ziehen kann, alle Shreds eines jeweiligen Threads auszusetzen. Die
Betriebssystemaufrufe, die zur Thread-Verwaltung benutzt werden,
werden durch Aufrufe einer Shred-Bibliothek auf Nutzerebene ersetzt.
Die Shred-Bibliothek
wiederum ruft das Betriebssystem auf, um nach Bedarf Threads zu
erzeugen und zu zerstören.
-
Shreds und Fibers
-
Shreds
unterscheiden sich von Fibers, die in Betriebssystemen des Stands
der Technik implementiert sind. Ein Überblick über diese Unterschiede ist
der folgenden Tabelle zu entnehmen:
Eigenschaft | Fiber | Shred |
Erzeugung | Ein
Thread kann mehrere Fibers erzeugen | Ein
Thread kann mehrere Shreds erzeugen |
Gleichzeitigkeit | Auf
einem Thread kann ein Fiber gleichzeitig ablaufen | Auf
einem Thread können
mehrere Shreds gleichzeitig ablaufen |
Scheduling | Das
Scheduling für
Fibers erfolgt durch Software mit Hilfe eines kooperativen Multitasking-Mechanismus | Das
Scheduling für
Shreds erfolgt durch Hardware mit Hilfe simultanem Multi-Threadings oder Chip-Multiprocessing |
Zustand | Jeder
Fiber weist seinen eigenen privaten Anwendungszustand auf | Jeder
Shred weist seinen eigenen privaten Anwendungszustand auf |
Zustandspeicherung | Der
Zustand des aktuell ablaufenden Fiber ist in Registern gespeichert.
Der Zustand inaktiver Fibers ist im Speicher gespeichert. | Der
Zustand jedes aktuell laufenden physikalischen Shreds ist auf Register
auf dem Chip gespeichert. Der Zustand inaktiver virtueller Shreds
ist im Speicher gespeichert. |
Zustandsverwaltung | Der
Zustand der aktuell ablaufenden Fiber wird vom Betriebssystem durch
einen Kontextwechsel gesichert/wiederhergestellt | Der
Anwendungszustand aller Shreds wird vom Betriebssystem durch einen
Kontextwechsel gesichert/wiederhergestellt |
Tabelle
6
-
Hardware-Implementierung
-
Die
Implementierung eines Mikroprozessors, der die Multi-Thread-Architekturerweiterungen
unterstützt,
kann die Form von Chip-Multiprozessoren (CMP) und simultanen Multi-Threadprozessoren
(SMT) annehmen. Die CMP- und SMT-Prozessoren des Stands der Technik
versuchen, das gemeinsame Nutzen von CPU-Ressourcen vor der Software
zu verbergen, während
ein Prozessor, wenn er mit den vorliegenden Ausführungsformen der Multi-Thread-Architekturerweiterungen
implementiert wird, die gemeinsame Nutzung als Teil der Architektur
freigibt.
-
Um
einen MAX-Prozessor als einen Chip-Multiprozessor zu implementieren,
wird ein Übertragungsmechanismus
benutzt, um mehrere Kopien des Systemzustand zwischen den CPU-Kernen synchronisiert
zu halten. Schnelle Kommunikationsbusse für den gemeinsamen Anwendungs-
und Systemzustand werden eingeführt.
Da auf dem Chip stattfindende Kommunikation im Vergleich zu Speicher
außerhalb
des Chips schneller ist, verleihen diese Kommunikationsbusse dem
MAX-Prozessor seinen Leistungsvorteil gegenüber einem gemeinsamen Speicher-Prozessor.
-
Das
Implementieren eines MAX-Prozessors als simultaner Multi-Threadprozessor
ist möglich,
da die Hardware bereits das notwendige gemeinsame Nutzen von Ressourcen
vorsieht. Es ist möglich,
MAX beinahe ausschließlich
in Mikrocode auf einem Multi-Thread-32-Bit-Prozessor zu implementieren.
-
Gemäß einer
Ausführungsform
erlaubt das vorliegende Verfahren und System die Priorisierung von Systemaufrufen
und Ausnahmen (die an das Betriebssystem gemeldet werden) zwischen
mehreren Shreds, sodaß zu
einem gegebenen Zeitpunkt nur die Anfrage jeweils eines Shreds bedient
wird. Die Priorisierung und Auswahl einer Anfrage ist nötig, da
der Systemzustand nur dazu in der Lage ist, eine Betriebssystemanfrage gleichzeitig
zu bearbeiten. Nehmen wir beispielsweise an, daß Shred 1 und Shred 2 gleichzeitig
einen Systemaufruf durchführen.
Der Priorisierer würde
sicherstellen, daß nur
der Systemaufruf von Shred 1 ausgeführt wird, und daß die Ausführung des
Systemaufrufs von Shred 2 noch nicht einsetzt. Aus Gründen der
Fairneß wendet
der Priorisierer einen Round-Robin-Auswahlalgorithmus an, obwohl
auch andere Auswahlalgorithmen benutzt werden können.
-
Skalierbarkeit
-
Die
Skalierbarkeit des MAX-Programmierungsmodells wird bestimmt durch:
- 1) Die Zahl von Zuständen, die für einen Kontextwechsel gesichert/wiederhergestellt
werden kann
- 2) Die Reduzierung von Parallelismus, die sich aus der Aussetzung
aller Shreds ergibt, die einem jeweiligen Thread während eines
Kontextwechsels zugeordnet sind
- 3) Die Kommunikation zwischen Shreds.
-
Während die
Anzahl von Shreds zunimmt, erhöht
sich auch die Zahl von Zuständen,
die für
einen Kontextwechsel gesichert/wiederhergestellt werden muß, und der
potentielle Parallelismus, der aufgrund der Aussetzung aller Shreds
verloren geht, nimmt zu. Diese zwei Faktoren begrenzen die praktische
Anzahl von Shreds.
-
Die
Kommunikation zwischen Shreds begrenzt die Skalierbarkeit ebenfalls,
da diese Kommunikation unter Benutzung von Ressourcen auf dem Chip
erfolgt. Im Gegensatz dazu wird die Skalierbarkeit des traditionellen
gemeinsamen Speicher-Multiprozessormodells durch Kommunikation außerhalb
des Chips beschränkt.
-
Gemeinsame Taxonomie
-
Eine
Taxonomie der verschiedenen Freiheitsgrade in Architektur, Implementierung
und Softwarenutzung von Shreds ist in der folgenden Tabelle aufgeführt:
Attribut | Option
1 | Option
2 | Option
3 |
Instruktionssatz-Architektur | Homogen – alle Shreds implementieren
dieselbe Instruktionssatz-Architektur | Heterogen – alle Shreds implementieren
unterschiedliche Instruktionssatz-Architekturen | |
Mikroarchitektur-Implementierung | Symmetrisch – alle Shreds
laufen auf derselben Hardware-Mikroarchitektur ab | Asymmetrisch – Shreds laufen
auf unterschiedlichen Hardware-Mikroarchitekturen ab | |
Anwendungsparallelismus | Sequentiell – Üblicher sequentieller
Code | Parallel – Parallelisierter Code | |
Shred-Erzeugung | Vom
Programmierer erzeugt – Shreds
werden explizit von dem Programmierer erzeugt | Kompiliert – Shreds
werden automatisch von dem Kompilierer erzeugt | Fixfunktion – Shreds sind
für bestimmte
Funktionen wie die Speicher-Bereinigung
festgelegt |
Richtigkeit
der Architektur | Architektonisch – Alle Shreds
tragen zu der Richtigkeit der Architektur des Programms bei | Hinweis – Einige
Shreds tragen zu der Richtigkeit der Architektur des Programms bei,
während andere
nur zur Leistung beitragen | |
Eingabe/Ausgabe | Berechnung – Shreds führen nur
Berechnungen durch | E/A – Shreds
führen
neben Berechnungen Eingabe/Ausgabe durch | |
Tabelle
7
-
Es
werden zwei verschiedene Typen von MAX-Architektur unterschieden:
homogen und heterogen. Homogene Shreds sind ähnlich wie homogene Multiprozessoren,
indem alle Shreds denselben Instruktionssatz ausführen. Heterogene
Shreds sind ebenfalls möglich,
in ähnlicher
Weise wie heterogene Multiprozessoren. Beispielsweise können heterogene
Shreds vorgesehen sein zwischen:
- – einem
32-Bit-Prozessor und einem Netzwerkprozessor,
- – einem
32-Bit-Prozessor und einem 64-Bit-Prozessor.
-
Ebenso
kann die zugrundeliegende Mikroarchitektur entweder symmetrisch
oder asymmetrisch sein. Ein Beispiel des letztgenannten Falls wäre ein Chip-Multiprozessor
mit einigen großen
Hochleistungs-CPU-Kernen und vielen kleinen Niedrigstrom-CPU-Kernen,
wie z. B. in 4 dargestellt.
-
Nutzungsmodelle
-
Die
folgende Tabelle gibt einen Überblick über eine
Reihe von Nutzungsmodellen für
Ausführungsformen
der vorliegenden Multi-Thread-Architekturerweiterungen:
Nutzungsmodell | Taxonomie | Beschreibung | Vorteil |
Prefetching | Homogene
ISA, sequentieller Code, vom Kompilierer erzeugt, Hinweis, Berechnung | Ein
Hilfsthread führt
ein Prefetching für
Speicherstellen vor einem Hauptthread aus. Der Hilfsthread wird
von dem Kompilierer erzeugt. | Beschleunigt
den Skalarcode mit signifikantem Zeitverbrauch für Cache-Misses. |
Ersetzung üblicher Threads | Homogene
ISA, paralleler Code, vom Programmierer erzeugt, architektonisch,
Berechnung | Die
Shreds werden anstelle üblicher
gemeinsamer Speicher-Threads
benutzt. Eine Bibliothek stellt Thread-Dienste anstelle des Betriebssystems
bereit. | Beschleunigt
Fadencode. Thread-Primitive werden um mehrere Größenordnungen schneller. |
Dedizierte
Ausführungs-Ressourcen für Kompilierer | Homogene
ISA, sequentieller Code, vom Kompilierer erzeugt, architektonisch,
Berechnung | Der
Kompilierer erzeugt mehrere Threads aus Skalarquellcode. | Der
Kompilierer hat direkte Kontrolle über Shreds. |
Dedizierte
Threads für verwaltete
Laufzeit-Umgebungen | Homogene
ISA, Fixfunktion, architektonisch, Berechnung | Shreds
dienen ausschließlich
Funktionen der Laufzeitverwaltung. Beispielsweise kann eine punktgerechte Übersetzung
und Speicherbereinigung mit Hilfe dedizierter Shreds durchgeführt werden. | Übersetzungs-
und Speicherbereinigungs-Shreds
werden prinzipiell frei. |
Parallele
Programmiersprachen | Homogene
ISA, paralleler Code, vom Programmierer erzeugt, architektonisch,
Eingabe/Ausgabe | Der
Programmierer erzeugt parallelen Code, der zu mehreren Shreds kompiliert
wird. | Thread-Primitive
sind schnell genug, um als Instruktionen benutzt zu werden. |
CPU
mit integrierten E/A-Funktionen | Heterogene
ISA, paralleler Code, vom Programmierer erzeugt, architektonisch,
Eingabe/Ausgabe | E/A-Funktionen
werden direkt von dem Anwendungsprogramm durchgeführt. Beispielsweise Graphiken
und Netzwerkverarbeitung. | Ermöglicht die
Integration von E/A-Funktionen direkt
in die CPU-Architektur. |
Simultane Mehr-ISA-CPU | Heterogene
ISA, asymmetrische Architektur, vom Programmierer erzeugt, architektonisch, Berechnung | Eine
einzige CPU implementiert mehrere ISAs, beispielsweise eine 32-Bit-Architektur
und eine 64-Bit-Architektur. Jede
ISA steht dem Programmierer als ein Shred zur Verfügung. | Interessante
Möglichkeit,
aber wahrscheinlich nicht nützlich. |
Asymmetrischer
Kernprozessor | Homogene
ISA, asymmetrische Architektur, architektonisch, Berechnung | Ein
CMP implementiert eine Mischung aus Kernen, beispielsweise mit hoher
Leistung und Niedrigstrom | Erzielen
einer guten Skalar- und Durchsatzleistung. |
Tabelle
8
-
Prefetching
-
Im
Prefetch-Nutzungsmodell bringt ein Hauptthread einen oder mehrere
Hilfsthreads hervor, die benutzt werden, um ein Prefetching von
Cache-Zeilen aus dem Hauptspeicher durchzuführen. Die Hilfsthreads werden
in Reaktion auf einen Cache-Miss am Hauptthread hervorgebracht.
Da ein Zugriff auf den Hauptspeicher den Abschluß mehrerer hundert bis tausend
CPU-Takte erfordert, wird die Ausführung von Skalarcode während eines
Hauptspeicherzugriffs effektiv eingestellt, es sei denn, in der
Architektur wird eine entsprechende Vorsorge getroffen, indem Load-Befehle,
die zu einem Cache-Miss führen,
ignoriert werden und ein Übergang
zum Hauptspeicher stattfindet.
-
Ersetzen üblicher Threads
-
Shreds
können
von Multi-Thread-Anwendungen als Hochleistungsersatz für übliche Threads
benutzt werden. Eine Softwarebibliothek der Nutzerebene wird bereitgestellt,
um Shred-Verwaltungsfunktionen
durchzuführen
(Erzeugen, Zerstören
usw.), die zuvor von dem Betriebssystem durchgeführt wurden. Die Bibliothek nutzt
die Shred-Instruktionen, und ruft auch bei Bedarf das Betriebssystem
auf, um zusätzliche
Threads anzufordern. Das Aufrufen einer Softwarebibliothek ist wesentlich
schneller als das Aufrufen des Betriebssystems, da kein Kontextwechsel
nötig ist.
-
Dedizierte Ausführungsressourcen für den Kompilierer
-
Der
Kompilierer kann die Shreds in derselben Weise benutzen, in der
er andere Prozessorressourcen wie z. B. Register benutzt. Beispielsweise
kann der Kompilierer den Prozessor als 8 Ganzzahlregister, 8 Gleitkommaregister,
8 SSE-Register und 4 Shreds aufweisend betrachten. Indem er Shreds
als Ressource behandelt, teilt der Kompilierer Shreds in ähnlicher
Weise zu, wie er Register zuteilt. Wie bei Registern wird ein Mechanismus
benötigt,
um einen Spill/Fill von Shreds an einen Hintergrundspeicher auszuführen für den Fall,
daß das
Anwendungsprogramm mehr virtuelle Shreds benötigt, als die Hardware bereitstellt.
-
Dedizierte Threads für verwaltete Laufzeitumgebungen
-
In
einer verwalteten Laufzeitumgebung dienen Shreds ausschließlich Funktionen
wie der Speicherbereinigung, der punktgerechten Kompilierung und
der Profilerstellung. Die Shreds führen solche Funktionen im wesentlichen „umsonst” aus, da
die Shreds als Teil der Instruktionssatz-Architektur (ISA) bereitgestellt
werden. Die ISA ist der Teil des Prozessors, der für den Programmierer
oder den Schreiber des Kompilierers sichtbar ist. Die ISA dient
als Grenze zwischen Software und Hardware.
-
Parallele Programmiersprachen
-
MAX
unterstützt
parallele Programmiersprachen und Hardware-Beschreibungssprachen
direkt. Beispielsweise erzeugt ein iHDL- oder Verilog-Kompilierer
direkt Code für
mehrere Shreds, da der Quellcode explizit parallel ist.
-
Die
große
Zahl von Threads, die von Chip-Multiprozessoren ermöglicht wird,
führt zur
Sprachunterstützung
des Multi-Threadings. Eine solche Unterstützung ist durch Aufrufe des
Betriebssystems und der Laufzeitbibliothek bereitgestellt. Die Sprachunterstützung für Multi-Threading wird in
allgemein gebräuchliche
Mehrzweck-Programmiersprachen migriert.
-
CPU mit integrierter E/A-Funktion
-
Die
Shreds werden benutzt, um E/A-Funktionen wie z. B. einen Netzwerk-Koprozessor
zu implementieren. Ein wichtiger Unterschied bei einem Netzwerk-Koprozessor,
der als ein Shred implementiert ist, besteht darin, daß er als
Teil der CPU und nicht als ein E/A-Gerät erscheint.
-
In
Systemen des Stands der Technik ruft das Anwendungsprogramm das
Betriebssystem mit Hilfe einer API (Anwendungsprogrammschnittstelle – Application
Program Interface) auf, wenn ein Anwendungsprogramm E/A benötigt. Das
Betriebssystem wiederum ruft einen Gerätetreiber auf, der die Anfrage
an das E/A-Gerät
sendet. Das Betriebssystem ist dafür zuständig, E/A-Anfragen von mehreren Anwendungsprogrammen
in Warteschlangen oder in Serie zu stellen, und sicherzustellen,
daß das
E/A-Gerät
nur eine Anfrage (oder eine endliche Anzahl von Anfragen) gleichzeitig
bearbeitet. Das ist nötig,
da der Zustand des E/A-Geräts
für das
System global ist, während
der CPU-Zustand zwischen mehreren Anwendungen gemultiplext wird.
-
Bei
einem E/A-Gerät,
das als ein heterogener Shred implementiert wird, wird der Zustand
des E/A-Geräts
als eine Erweiterung des Anwendungszustands der CPU behandelt. Das
Anwendungsprogramm steuert sowohl den Anwendungszustand der CPU
als auch den Zustand des E/A-Geräts
direkt. Die Architektur des E/A-Geräts ist so gestaltet, daß dessen
Zustand zwischen mehreren Anwendungen ohne negative Auswirkungen
gemultiplext werden kann.
-
Simultane Mehr-ISA-CPU
-
Die
64-Bit-Architektur ist mit Hilfe eines Mechanismus, der als „seamless” (nahtlos)
bekannt ist, dafür definiert,
die Anwendungsarchitektur mit 32-Bit-Architektur sowie den neuen
64-Bit-Instruktionssatz
zu enthalten. Die Kompatibilität
mit dem 32-Bit-Architekturinstruktionssatz erlaubt es Prozessoren
mit 64-Bit-Architektur, sowohl existierende Anwendungen mit 32-Bit-Architektur als auch
neue Anwendungen mit 64-Bit-Architektur ablaufen zu lassen.
-
Gemäß der vorliegenden
Definition läuft
zu einem jeweiligen Zeitpunkt auf einer CPU mit 64-Bit-Architektur entweder
ein Thread mit 64-Bit-Architektur oder ein Thread mit 32-Bit-Architektur ab. Das
Wechseln zwischen den zwei ISAs wird durch die Instruktionen 64-Bit-Architektur br.ia
(Abzweig zu 32-Bit-Architektur) und 32-Bit-Architektur jmpe (Sprung
zu 64-Bit-Architektur)
erreicht. Die 32-Bit-Architekturregister sind den 64-Bit-Architekturregistern
zugeordnet, sodaß nur
eine Kopie des Zustands benötigt
wird.
-
Es
ist möglich,
eine Mehr-ISA-CPU zu erzeugen, in der mehr als eine InstruktionssatzArchitektur
zu einem jeweiligen Zeitpunkt abläuft. Dies kann erreicht werden,
indem ein Shred für
die ISA mit 64-Bit-Architektur und ein zweiter Shred für die ISA
mit 32-Bit-Architektur benutzt wird. Wie bei homogenen Shreds muß ein distinktiver
Anwendungszustand sowohl für
den 64-Bit-Architektur-Shred als auch für den 32-Bit-Architektur-Shred
bereitgestellt sein. Der 64-Bit-Architektur-Shred und der 32-Bit-Architektur-Shred
laufen simultan ab.
-
Nach
erfolgter Beschreibung der Merkmale des vorliegenden Verfahrens
und Systems zum Bereitstellen eines Multi-Threadings auf Nutzerebene
durch die oben beschriebenen Multi-Thread-Architekturerweiterungen soll
im folgenden eine Ausführungsform
für 32-Bit-Systeme
dargestellt werden.
-
Ausführungsform
mit 32-Bit-Architektur
-
Obwohl
unter Bezugnahme auf die IA-32-Architektur beschrieben, wird der
Leser verstehen, daß die hier
beschriebenen Verfahren und Systeme auf andere Architekturen angewandt
werden können,
wie z. B. die IA-64-Architektur. Auch wird der Leser erneut auf 5 verwiesen,
um eine beispielhafte Ausführungsumgebung
gemäß einer
Ausführungsform
der vorliegenden Erfindung zu verstehen. Eine kleine Zahl von Instruktionen
wird der IA-32-ISA zusammen mit einer Zahl von Registern 650 bis 660 hinzugefügt, um der
IA-32 die Möglichkeit
eines Multi-Threadings
auf Nutzerebene zu verleihen.
-
Die
Multi-Thread-Architekturerweiterungen bestehen aus folgendem Zustand:
- – Ein
modellspezifisches Register 650 (MAX_SHRED_ENABLE), das
von dem Betriebssystem oder dem BIOS zum Aktivieren/Deaktivieren
der Erweiterungen benutzt wird.
- – Drei
Bits in der CPU-ID zur Erweiterungsfunktionsinformation, die anzeigen,
ob der Prozessor die Erweiterungen implementiert, sowie die Anzahl
verfügbarer
physikalischer Shreds.
- – Replikation
des Großteils
des Anwendungszustands (EAX, EBX usw.), sodaß jeder Shred über eine
eigene private Kopie des Anwendungszustands verfügt.
- – Ein
Satz gemeinsamer Register SH0–SH7 655,
die zur Kommunikation und Synchronisation zwischen Shreds benutzt
werden kann.
- – Ein
Satz Steuerregister SC0–SC4 660,
die zur Shred-Verwaltung benutzt werden.
-
Die
Multi-Thread-Architekturerweiterung ist aus den folgenden Instruktionen
zusammengesetzt:
- – Shred-Erzeugung/Zerstörung: Forkshred,
haltshred, killshred, joinshred, getshred
- – Kommunikation:
mov in/aus gemeinsames Register 655, synchrones mov in/aus
gemeinsames Register 655
- – Synchronisation
(Semaphor): cmpxshgsh, xaddsh, xchgsh
- – Signalisierung:
signalshred
- – Übergang
in/aus Multi-Shred-Modus: entermsm, exitmsm
- – Zustandsverwaltung:
shsave, shrestore
- – Verschiedenes:
mov in/aus Shred-Steuerregister
-
Außerdem sind
für die
IA-32-Mechanismen die folgenden Funktionen vorgesehen.
- – Der
IA-32-Ausnahmemechanismus verläßt den Multi-Shred-Modus
und sichert alle Shred-Zustände an einer
Ausnahme (wenn zutreffend).
- – Die
Instruktion IA-32 IRET stellt alle Shred-Zustände wieder her und kehrt in
den Multi-Shred-Modus
zurück
(wenn zutreffend).
- – Ein
Ausnahmemechanismus auf Nutzerebene wird eingeführt.
-
Konfigurierung
-
Ein
modellspezifisches Register (MSR)
650 wird benutzt, um
die Multi-Thread-Architekturerweiterung zu
aktivieren. Das MSR ist im folgenden beschrieben.
Registeradresse (Hex) | Registeradresse (Dezimal) | Felder
und Bitschalter für
Registernamen | Gemeinsam/Individuell | Bit-Beschreibung |
1F0H | 496 | MAX_SHRED_ENABLE | Gemeinsam | Bit
0 aktiviert die Multi-Thread-Architekturerweiterung.
Initialisiert auf 0 bei Rücksetzung.
Das Betriebssystem oder BIOS müssen MAX
explizit aktivieren, indem sie dieses Register mit eins beschreiben. |
Tabelle
9
-
Modellspezifische
Register wie z. B. Shred-MSR
650 werden nur auf Privilegstufe
0 gelesen und beschrieben. Wenn die Multi-Thread-Architekturerweiterungen
nicht aktiviert sind, ist die Ausführung des bestehenden Codes
auf Shred Nummer 0 beschränkt.
EAX-Ausgangswert | Zum
Prozessor bereitgestellte Information |
1H | EAX-Versionsinformation
(Typ, Familie, Modell und Stepping-ID)
EBX
Bits 7–0: Markenindex
Bits
15–8:
CLFLUSH-Zeilengröße (Wert
0,8 = Cache-Zeilengröße in Bytes)
Bits
32–16:
Anzahl logischer Prozessoren pro physikalischem Prozessor
Bits
31–24:
Lokale APIC-ID
ECX Erweiterungsfunktionsinformation
EDX
Funktionsinformation |
Tabelle
10
-
CPUID
-
Die
IA-32 CPUID-Instruktion wird modifiziert, um eine Anzeige zurückzusenden,
daß der
Prozessor die Multi-Thread-Architekturerweiterung unterstützt, zusammen
mit einem Zähler
für die
Zahl bereitgestellter physikalischer Shreds. Dies erfolgt, indem
drei Bits (NSHRED) der in EXC zurückgesendeten Funktionsinformation
hinzugefügt
werden. Die von der CPUID-Instruktion
zurückgesendete
Information ist in der folgenden Tabelle dargestellt:
EAX-Ausgangswert | Zum
Prozessor bereitgestellte Information |
1H | EAX-Versionsinformation
(Typ, Familie, Modell und Stepping-ID)
EBX
Bits 7–0: Markenindex
Bits
15–8:
CLFLUSH-Zeilengröße (Wert
0,8 = Cache-Zeilengröße in Bytes)
Bits
32–16:
Anzahl logischer Prozessoren pro physikalischem Prozessor
Bits
31–24:
Lokale APIC-ID
ECX Erweiterungsfunktionsinformation
EDX
Funktionsinformation |
Tabelle
11
-
Die
im ECX-Register zurückgesendete
Erweiterungsfunktionsinformation weist die folgende Form auf:
Bit
# | Mnemonisches
Symbol | Beschreibung |
18:16 | NSHRED | Drei
Bits, die die Anzahl der von der Hardware unterstützten physikalischen
Shreds anzeigen.
000: 1 Shred/Thread
001: 2 Shreds/Thread
010:
4 Shreds/Thread
011: 8 Shreds/Thread
100: 16 Shreds/Thread
101:
32 Shreds/Thread
110: Reserviert
111: Reserviert |
Tabelle
12
-
Wenn
die Multi-Thread-Architekturerweiterung nicht aktiviert wird (durch
das MSR MAX_SHRED_ENABLE), sendet die Erweiterungsfunktionsinformationen
einen Wert von 0 für
NSHRED zurück.
-
Architekturzustand
-
Die
Multi-Thread-Architekturerweiterung teilt den gesamten Zustand in
eine von drei Kategorien ein.
- – Privat
für jeden
Shred
- – Gemeinsam
für lokale
Shreds
- – Gemeinsam
für alle
Shreds
-
Eine
Unterteilung des IA-32-Zustands in die genannten Kategorien ist
oben in Tabelle 2 gezeigt.
-
Der
Privatzustand des Shreds wird einmal pro Shred repliziert. Der private
Shred-Zustand wird einmal pro Shred repliziert. Insbesondere stellt
die Architektur keine Instruktionen bereit, die einzeln die privaten
Register eines Shreds von einem anderen ablesen oder beschreiben.
Die Architektur stellt die Instruktionen shsave und shrestore bereit,
um den gesamten privaten Shred-Zustand
in Speicher zu schreiben und zu lesen, doch werden diese Instruktionen
nur im Einzel-Shred-Modus
ausgeführt.
Der gemeinsame Shred-Zustand ist oben in Tabelle 3 gezeigt.
-
Ein
Satz von gemeinsamen Registern SH0–SH7 655 werden zur
Kommunikation und Synchronisation zwischen Shreds benutzt. Diese
Register 655 werden durch die Instruktionen MOV in gemeinsames
Register und MOV aus gemeinsamem Register geschrieben und abgelesen.
Die Register SH0–SH7 655 speichern 32-Bit-Integerwerte.
Gemäß einer
Ausführungsform
werden 80-Bit-Gleitkommadaten 625 und 128-Bit-SSE-Daten 640 über den
Hauptspeicher gemeinsam genutzt.
-
Ein
Satz von Shred-Steuerregistern SC0–SC4
660 ist vorgesehen.
Diese Register sind wie folgt definiert.
Register | Name | Beschreibung |
SC0 | Shred-Ablaufregister | SC0
enthält
einen Bitvektor mit einem Bit pro Shred. Bit 0 entspricht Shred
0; Bit 1 entspricht Shred 1 usw. Jedes Bit zeigt an, ob der zugeordnete
Shred gegenwärtig
abläuft
oder angehalten ist. Wenn die Multi-Thread-Architekturerweiterung
durch das MSR MAX_SHRED_ENABLE deaktiviert ist, enthält SC0 einen
Wert von 1, was anzeigt, daß nur
Shred 0 aktiv ist. |
SC1 | Shred-Ablauf-Interruptregister | Der
Inhalt von SC0 wird an SC1 kopiert, wenn ein Übergang vom Multi-Shred-Modus in Einzel-Shred-Modus
erfolgt, und der Inhalt von SC1 wird in SC0 kopiert, wenn ein Übergang
vom Einzel-Shred-Modus
in Multi-Shred-Modus erfolgt. |
SC2 | Zeiger
zum Sichern/Wiederherstellen des Shred-Zustands | SC2
zeigt auf den Speicherbereich zum Sichern/Wiederherstellen des Shred-Zustands.
Dieser Speicherbereich wird benutzt, um den Zustand aller ablaufenden
Shreds bei einem Kontextwechsel zu sichern und wiederherzustellen. |
SC3 | Leer/Voll-Bits
des gemeinsamen Registers | SC3
enthält
die Leer/Voll-Bits für
die gemeinsamen Register. Bit 0 entspricht sh0; Bit 1 entspricht
sh1 usw. |
SC4 | Basisadresse
der Interrupttabelle auf Nutzerebene | SC4
zeigt auf die Basisadresse der Interrupttabelle auf Nutzerebene. |
Tabelle
13
-
Der
Speicherzustand wird von allen Shreds gemeinsam genutzt. Die Unterteilung
des Registers EFLAGS
615 ist in der folgenden Tabelle gezeigt.
Bit | Typ | Repliziert | Mnemonisches Symbol | Beschreibung |
0 | Zustand | J | CF | Übertragflag |
2 | Zustand | J | PF | Paritätsflag |
4 | Zustand | J | AF | Hilfsübertragflag |
6 | Zustand | J | ZF | Nullflag |
7 | Zustand | J | SF | Vorzeichenflag |
8 | System | J | TF | Einzelschrittflag |
9 | System | N | IE | Interrupt-Aktivierungsflag |
10 | Steuerung | J | DF | Richtungsflag |
11 | Zustand | J | OF | Überlaufflag |
13:
12 | System | N | IOPL | E/A-Privilegstufe |
14 | System | N | NT | Geschachtelte Task |
16 | System | N | RF | Wiederaufnahme-Flag |
17 | System | N | VM | Virtueller
86-Modus |
18 | System | N | AC | Ausrichtungs-Prüfung |
19 | System | N | VIF | Virtuelles
Interrupt-Flag |
20 | System | N | VIP | Virtuelles
Interrupt schwebend |
21 | System | N | ID | ID-Flag |
Tabelle
14
-
Mit „J” markierte
Flags werden pro Shred repliziert. Mit „N” markierte Flags verfügen über eine
allen Shreds gemeinsame Kopie.
-
Die
Das 32-Bit-EFLAGS-Register 615 enthält eine Gruppe von Zustands-Flags,
ein Steuerflag, und eine Gruppe von Systemflags. Nach der Initialisierung
des Prozessors 105 (entweder durch Assertieren des RESET-Pin
oder des INIT-Pin) ist der Zustand des EFLAGS-Registers 00000002H.
Die Bits 1, 3, 5, 15, und 22 bis 31 dieses Registers 615 sind
reserviert. Die Software sollte die Zustände dieser Bits nicht benutzen
oder sich auf sie verlassen.
-
Einige
der Flags im EFLAGS-Register 615 können direkt mit Hilfe speziell
dafür vorgesehener
Instruktionen modifiziert werden. Es gibt keine Instruktionen, die
eine Prüfung
oder Modifizierung des gesamten Registers erlauben. Allerdings können die
folgenden Instruktionen benutzt werden, um Gruppen oder Flags in
und aus dem Procedure Stack oder EAX-Register zu verschieben: LAHF,
SAHF, PUSHF, PUSHFD, POPF und POPFD. Nachdem der Inhalt des EFLAGS-Registers 615 an
den Procedure Stack oder das EAX-Register übertragen wurde, können die
Flags mit Hilfe der Instruktionen zur Bitmanipulation des Prozessors
(BT, BTS, BTR und BTC) geprüft
und modifiziert werden.
-
Beim
Aussetzen einer Task (mit Hilfe der Multitasking-Funktionen des
Prozessors) speichert der Prozessor automatisch den Zustand des
EFLAGS-Registers 615 in dem Task-Statussegment (TSS) für die ausgesetzte
Task. Wenn er sich an eine neue Task anbindet, lädt der Prozessor das EFLAGS-Register 615 mit Daten
von dem TSS der neuen Task.
-
Wenn
ein Aufruf eines Interrupt- oder Ausnahmesteuerungsvorgangs erfolgt,
speichert der Prozessor automatisch den Zustand des EFLAGS-Registers 615 im
Procedure Stack. Wenn ein Interrupt oder eine Ausnahme mit Hilfe
eines Task-Wechsels bearbeitet wird, wird der Zustand des EFLAGS-Registers 615 für die ausgesetzte
Task im TSS gespeichert.
-
Erzeugung/Zerstörung von Shreds
-
Ein
Shred kann mit Hilfe der Instruktion forkshred erzeugt werden. Das
Format ist
forkshred | imm16,
Ziel-IP |
forkshred | r16,
Ziel-IP |
-
Es
sind zwei Formen vorgesehen, wobei bei der einen die Shred-Nummer
als unmittelbarer Operand dient, und die Shred-Nummer bei einer
zweiten als Register-Operand dient. Bei beiden Formen ist die Ziel-IP als
ein unmittelbarer Operand festgelegt, dessen Wert im Verhältnis zu
dem Beginn des Codesegments (nominell 0) steht, und nicht zu der
aktuellen IP.
-
Die
Codierung forkshred imm16, Ziel-IP ist ähnlich wie die Instruktion
Far-Jump, wobei die Shred-Nummer den 16-Bit-Selektor ersetzt, und
die Ziel-IP den 16/43-Bit-Offset ersetzt.
-
Die
Instruktion forkshred schaltet das geeignete Ablauf-Bit in SC0,
und beginnt die Ausführung
an der spezifizierten Adresse. Anders als der Systemaufruf fork()
von Unix kopiert die Instruktion forkshred den Zustand des Muttershreds
nicht. Ein neuer Shred beginnt die Ausführung mit einem aktualisierten
EIP, zusammen mit den aktuellen Werten aller anderen privaten Register.
Es wird erwartet, daß der
neue Shred sein Stack durch Laden von ESP initialisiert, und eingehende
Parameter aus gemeinsamen Registern oder gemeinsamem Speicher abruft.
Die Instruktion forkshred gibt Parameter nicht automatisch weiter.
-
Wenn
der Ziel-Shred bereits abläuft,
erzeugt forkshred eine #SNA-(Shred nicht verfügbar)-Ausnahme. Dies ist eine Ausnahme der
Nutzerebene, wie unten beschrieben. Die Software stellt entweder
sicher, daß sie nicht
versucht, einen bereits ablaufenden Shred zu starten, oder stellt
alternativ ein #SNA-Steuerungsprogramm bereit, das den existierenden
Shred anhält
und zurückgeht,
um forkshred erneut auszuführen.
Eine #GP(0)-Ausnahme wird erzeugt, wenn die Shred-Nummer höher ist
als die maximale Anzahl von Shreds, die von der Hardware unterstützt wird.
-
Um
die Ausführung
des aktuellen Shred zu beenden, wird die Instruktion haltshred benutzt.
Haltshred gibt das Ablaufbit des aktuellen Shreds in SC0 frei, und
beendet die Ausführung
des aktuellen Shreds. Der private Zustand des Shred wird auch nach
dem Anhalten beibehalten. Da kein Mechanismus dafür vorliegt, daß ein Shred
auf den privaten Zustand eines anderen Shred zugreift, ist der private
Zustand eines angehaltenen Shreds nicht sichtbar. Allerdings bleibt
der Zustand bestehen und wird sichtbar, wenn der Shred über forkshred
erneut mit der Ausführung
beginnt.
-
Um
die Ausführung
eines anderen Shred vorzeitig zu beenden, wird die Instruktion killshred
eingeführt. Das
Format ist
killshred | imm16 |
killshred | r16 |
-
Gemäß einer
Ausführungsform
ist die Shred-Nummer ein 16-Bit-Register oder ein unmittelbarer
Operand. Killshred gibt das Ablaufbit des spezifizierten Shreds
in SC0 frei, und beendet die Ausführung des Shreds. Während des
Anhaltens wird der private Zustand des Shreds beibehalten.
-
Wenn
der Ziel-Shred nicht abläuft,
wird killshred stillschweigend ignoriert. Dieses Verhalten ist nötig, um
ein Rennen zwischen killshred und einem normal beendenden Shred
zu vermeiden. Nach dem Ausführen von
killshred ist für
die Software gewährleistet,
daß der
Ziel-Shred nicht länger
abläuft.
Anstelle der Ausführung eines
haltshred kann ein Shred sich selbst beenden. eine #GP(0)-Ausnahme
wird erzeugt, wenn die Shred-Nummer höher ist als die maximale Anzahl
von Shreds, die von der Hardware unterstützt wird.
-
Um
zu warten, bis ein spezifizierter Shred beendet ist (wie durch die
Freigabe von SC0 angezeigt), wird die Instruktion joinshred eingeführt. Das
Format ist:
joinshred | imm16 |
joinshred | r16 |
-
Wenn
der Ziel-Shred nicht abläuft,
kehrt joinshred sofort zurück.
Dieses Verhalten verhindert ein Rennen zwischen joinshred und einem
normal endenden Shred. Nach der Ausführung von joinshred ist für die Software
gewährleistet,
daß der
Ziel-Shred nicht länger
abläuft.
Es ist für
einen Shred legal (aber nutzlos), einen joinshred an sich selbst
auszuführen.
Eine #GP(0)-Ausnahme
wird erzeugt, wenn die Shred-Nummer höher ist als die maximale Anzahl
von Shreds, die von der Hardware unterstützt wird. Die Instruktion joinshred
leitet nicht automatisch einen Rückgabewert
weiter. Um es einem Shred zu erlauben, seine eigene Shred-Nummer zu
bestimmen, wird die Instruktion getshred eingeführt. Das Format ist:
-
Getshred
gibt die Nummer des aktuellen Shred wieder. Getshred kann benutzt
werden, um auf Speicher-Arrays zuzugreifen, die nach Shred-Nummer
indiziert sind. Getshred nimmt eine Nullerweiterung der 16-Bit-Shred-Nummer
vor, um alle Bits des Zielregisters zu beschreiben.
-
Für alle Instruktionen
zur Erzeugung/Zerstörung
von Shreds kann die Shred-Nummer entweder als ein Register oder
ein unmittelbarer Operand spezifiziert werden. Es wird erwartet,
daß die
Ausführung
der unmittelbaren Form schneller ist als die Ausführung der
Registerform, da die Shred-Nummer eher bei der Decode-Time als bei
der Execute-Time verfügbar
ist. Bei der unmittelbaren Form weist der Kompilierer die Shred-Nummern
zu. Bei der Registerform wird eine Laufzeitzuweisung benutzt.
-
Die
folgende Tabelle gibt einen Überblick über die
Instruktionen zur Erzeugung/Zerstörung von Shreds.
Instruktion | Beschreibung |
forkshred
imm16, Ziel-IP
forkshred r16, Ziel-IP | Beginnt
die Shred-Ausführung
an der spezifizierten Adresse |
haltshred | Beendet
den aktuellen Shred |
killshred
imm16
killshred r16 | Beendeten
den spezifizierten Shred |
joinshred
imm16
joinshred r16 | Wartet,
bis der spezifizierte Shred endet |
getshred
r32 | Gibt
die Nummer des aktuellen Shreds wieder |
Tabelle
15
-
Die
Instruktionen forkshred, haltshred, killshred, joinshred und getshred
können
auf jeder Privilegstufe ausgeführt
werden. Haltshred ist eine nichtprivilegierte Instruktion, während die
existierende IA-32-hlt-Instruktion privilegiert ist.
-
Es
ist möglich,
daß die
Ausführung
von killshred oder haltshred zu Nullablauf-Shreds führt. Dieser
Zustand (mit 0 in SC0) ist anders als der existierende IA-32-Halt-Zustand.
SC0 = 0 ist ein legaler Zustand, jedoch nutzlos, bis ein Timer-Interrupt
auf Nutzerebene erzeugt wird.
-
Kommunikation
-
Shreds
kommunizieren miteinander über
existierenden gemeinsamen Speicher und über einen Satz von Registern,
die speziell für
diesen Zweck eingeführt
werden. Gemeinsame Register SH0–SH7 655 sind
für alle
lokalen Shreds zugänglich,
die zu demselben Thread gehören.
Die Register SH0–SH7 655 können benutzt werden,
um eingehende Parameter an einen Shred weiterzuleiten, Rückgabewerte
von einem Shred mitzuteilen, und Semaphor-Operationen durchzuführen. Eine
Konvention der Software weist jedem Zweck spezifische gemeinsame
Register 655 zu.
-
Jedes
gemeinsame Register
655 weist in SC3 ein entsprechendes
Leer/Voll-Bit auf. Um die gemeinsamen Register
655 zu beschreiben
und zu lesen, werden die Instruktionen MOV in gemeinsames Register
655 und
MOV aus gemeinsamem Register
655 benutzt. Diese sind im Überblick
wie folgt gestaltet:
mov | r32,
sh0–sh7 |
mov | sh0–sh7, r32 |
-
Die
Instruktionscodierungen sind ähnlich
wie die der existierenden Instruktionen MOV in/aus Steuerregister 660 und
MOV in/aus Debug-Register. Die Instruktionen MOV in/aus gemeinsames
Register können auf
jeder Privilegstufe ausgeführt
werden. Diese Instruktionen gehen davon aus, daß Software die Synchronisation
mit Hilfe weiterer Instruktionen explizit vornimmt. Die Instruktionen
mov in/aus gemeinsames Register prüfen oder modifizieren den Zustand
der Leer/Voll-Bits in SC3 nicht.
-
Es
wird erwartet, daß die
Wartezeit von MOV in gemeinsames Register 655 und MOV aus
gemeinsamem Register 655 niedriger ist als die Wartezeit
von Loads und Stores an den gemeinsamen Speicher. Es ist wahrscheinlich,
daß die
Hardware-Implementierung die gemeinsamen Register 655 spekulativ
abliest und nach anderen Shred-Beschreibungen schnüffelt. Die
Hardware muß beim
Beschreiben der gemeinsamen Register 655 das Äquivalent
der strengen Ordnung sicherstellen. In einer alternativen Ausführungsform
können Barriereinstruktionen
zum Zugreifen auf die gemeinsamen Register 655 erzeugt
werden.
-
Eine
Architekturfunktion hält
die Ordnung der gemeinsamen Register und die Speicherordnung voneinander
getrennt. Wenn also ein Shred ein gemeinsames Register 655 beschreibt,
und anschließend
den Speicher 120, ist nicht gewährleistet, daß der Inhalt
des gemeinsamen Registers 655 vor dem Inhalt des gemeinsamen
Speichers sichtbar ist. Der Grund für diese Definition ist, schnellen
Zugang/schnelle Aktualisierung von Schleifenzählern in den gemeinsamen Register 655 zu
ermöglichen,
ohne unnötige
Speicherbarrieren zu erzeugen. Wenn die Software Barrieren sowohl
für die
gemeinsamen Register 655 als auch den Speicher erfordert,
sollte die Software sowohl einen gemeinsamen Register-Semaphor als
auch einen Speicher-Semaphor durchführen. Der Speicher-Semaphor
ist redundant und dient lediglich als Barriere.
-
Um
schnelle Kommunikation sowie Synchronisation bereitzustellen, werden
die Instruktionen synchrones mov in/aus gemeinsamem Register benutzt.
Diese Instruktionen sind im Überblick
wie folgt gestaltet:
syncmov | r32,
sh0–sh7 |
syncmov | sh0–sh7, r32 |
-
Die
Instruktionscodierungen sind parallel zu den existierenden Instruktionen
MOV in/aus Steuerregister 660 und MOV in/aus Debug-Register.
Die Instruktion synchrones mov in/aus gemeinsamem Register 655 ist ähnlich wie
ihr asynchrones Gegenstück,
nur daß sie
wartet, bis das Leer/Voll-Bit leer anzeigt, bevor sie das gemeinsame
Register 655 beschreibt. Nach Beschreiben des gemeinsamen
Registers 655 wird das Leer/Voll-Bit auf voll geschaltet.
Die Instruktion synchrones mov in/aus gemeinsamem Register 655 ähnelt ihrem
asynchronen Gegenstück,
nur daß sie
wartet, bis das leere/volle Bit voll anzeigt, bevor sie das gemeinsame
Register 655 abliest. Nach Ablesen des gemeinsamen Registers 655 wird
das Leer/Voll-Bit auf leer geschaltet.
-
Die
Leer/Voll-Bits können
mit einem Übergang
zu SC3 wie folgt initialisiert werden. Die Instruktionen synchrones
mov in/aus gemeinsamem Register
655 können auf jeder Privilegstufe
ausgeführt
werden. Die Kommunikationsinstruktionen für gemeinsame Register sind
im folgenden zusammengefaßt:
Instruktion | Beschreibung |
mov
r32, sh0–sh7 | Verschieben
aus gemeinsamem Register |
mov
sh0–sh7,
r32 | Verschieben
in gemeinsames Register |
syncmov
r32, sh0–sh7 | Synchrones
Verschieben aus gemeinsamem Register |
syncmov
sh0–sh7,
r32 | Synchrones
Verschieben in gemeinsames Register |
Tabelle
16
-
Synchronisationen
-
Ein
Satz von Synchronisationsprimitiven bearbeiten die gemeinsamen Register
655.
Die Synchronisationsprimitive sind ähnlich wie existierende Semaphor-Instruktionen,
nur daß sie
an den gemeinsamen Registern
655 operieren, und nicht an
dem Speicher. Die Instruktionen sind wie folgt.
Instruktion | Beschreibung |
cmpxchgsh
sh0–sh7,
r32 | Vergleich
des gemeinsamen Registers mit r32. Wenn gleich, wird ZF geschaltet,
und r32 wird in das gemeinsame Register geladen. Ansonsten wird
ZF freigegeben, und das gemeinsame Register wird in FAX geladen. |
xaddsh
sh0–sh7,
r32 | Austauschen
des gemeinsamen Registers gegen r32. Dann Hinzufügen von r32 in das gemeinsame Register.
Diese Instruktion kann mit dem LOCK-Präfix benutzt werden, um atomare
Operation zu ermöglichen. |
xchgsh
sh0–sh7,
r32 | Austauschen
des gemeinsamen Registers gegen r32. Diese Instruktion ist stets
atomar. |
Tabelle
17
-
Die
Synchronisationsprimitive werden auf jeder Privilegstufe ausgeführt. Diese
Instruktionen prüfen oder
modifizieren den Zustand der Leer/Voll-Bits in SC3 nicht.
-
Eintreten in/Beenden des Multi-Shred-Modus
-
Die
MAX-Architektur stellt einen Mechanismus bereit, um zwischen dem
Multi-Shred-Modus und dem Einzel-Shred-Modus hin- und herzuwechseln.
Der Einzel-Shred-Modus erlaubt es dem Prozessor, Kontextwechsel
in geordneter Weise durchzuführen,
indem die Ausführung
von allen Shreds bis auf einen angehalten wird. SC0 zeigt den vorliegenden
Betriebsmodus wie folgt an:
- – Wenn SC0
genau eine einzige „1” an jeder
Bitposition enthält,
impliziert dies den Einzel-Shred-Modus.
- – Wenn
SC0 etwas anderes als eine einzige „1” an jeder Bitposition enthält, impliziert
dies den Multi-Shred-Modus.
-
Um
einen Kontextwechsel durchzuführen,
ist es nötig:
- 1) alle Shreds bis auf einen auszusetzen, indem
in den Einzel-Shred-Modus gewechselt wird,
- 2) den Shred-Zustand zu sichern,
- 3) einen neuen Shred-Zustand zu laden,
- 4) die Ausführung
aller Shreds zum Wechseln in den Multi-Shred-Modus wiederaufzunehmen.
-
Die
Instruktionen entermsm und exitmsm werden benutzt, um jeweils in
den Einzel-Shred-Modus
bzw. in den Multi-Shred-Modus zu wechseln. Entermsm wird benutzt,
um in den Multi-Shred-Modus
einzutreten. Der Zustand aller Shreds muß vor der Ausführung dieser
Instruktion geladen werden. Entermsm kopiert den neuen Shred-Ablaufvektor
in SC1 nach SC0. Entermsm startet dann die spezifizierten Shreds.
-
Es
ist möglich,
daß der
Inhalt von SC1 dazu führt,
daß keine
weiteren Shreds nach der Ausführung von
entermsm ablaufen. In diesem Fall verbleibt der Prozessor im Einzel-Shred-Modus. Es ist auch
möglich, daß als Resultat
der Ausführung
von entermsm der Shred, für
den entermsm ausgeführt
wurde, nicht länger abläuft. Exitmsm
wird benutzt, um den Multi-Shred-Modus
zu beenden. Exitmsm kopiert den gegenwärtigen Shred-Ausführungsvektor
in SC0 nach SC1. Alle SC0-Ablaufbits, die nicht dem Shred, der exitmsm
ausführt, zugeordnet
sind, werden freigegeben. Alle Shreds bis auf den, der exitmsm ausführt, werden
angehalten. Diese Operationen werden in einer atomaren Sequenz durchgeführt. Der
SC0-Zustand zeigt den Einzel-Shred-Modus an. Entermsm und exitmsm
können
auf jeder Privilegstufe ausgeführt
werden.
-
Zustandsverwaltung
-
Die
Instruktionen (shsave und shrestore) werden benutzt, um den kollektiven
Shred-Zustand zu sichern bzw. wiederherzustellen, um den Inhalt
aller Privatzustand-Shreds in den Speicher zu schreiben bzw. den
Inhalt aller Privatzustand-Shreds aus dem Speicher abzulesen. Das
Format ist:
shsave | m16384 |
shrestore | m16384 |
-
Die
Adresse des Speicherbereichs wird als Verschiebeanteil in der Instruktion
spezifiziert. Die Adresse ist an einer 16-Byte-Grenze ausgerichtet.
Der Speicherbereich beträgt
16 KBytes, um eine künftige
Erweiterung zuzulassen. Der Speicherbereich erweitert das existierende
FXSAVE/FXRESTOR-Format durch Hinzufügen der Integer-Register. Der
Speicherbereich für
jeden Shred ist wie folgt definiert:
Offset | Register |
0–1 | FCW |
2–3 | FSW |
4–5 | FTW |
6–7 | FOP |
8–11 | HP |
12–13 | CS |
14–15 | Reserviert |
16–19 | FPU
DP |
20–21 | DS |
22–23 | Reserviert |
24–27 | MXCSR |
28–31 | MXCSR,
MASK |
32–159 | ST0–ST7 |
160–287 | XMM0–XMM7 |
288–351 | EAX,
EBX, ECX, EDX, ESI, EDI, EBP, ESP |
352–359 | ES,
FS, GS, SS |
360–367 | EIP |
368–371 | EFLAGS |
Tabelle
18
-
Der
Inhalt aller Shreds wird an einer Adresse gesichert/wiederhergestellt,
die sich ergibt aus: Adresse = 512·(Shred-Nummer)
+ (Basisadresse)
-
Der
Speicherbereich enthält
EIP und ESP des gegenwärtig
ablaufenden Shreds. Shsave schreibt den aktuellen EIP und ESP in
den Speicher. Um Branching zu vermeiden, überschreibt die Instruktion
shrestore nicht den EIP oder ESP des aktuellen Shreds. Die Funktion
shrestore, wenn sie als Teil eines IRET ausgeführt wird, überschreibt den EIP oder ESP
des aktuellen Shreds.
-
Shsave
uns shrestore können
auf jeder Privilegstufe ausgeführt
werden, aber nur im Einzel-Shred-Modus.
Eine #GP(0)-Ausnahme wird erzeugt, wenn shsave oder shrestore im
Multi-Shred-Modus
versucht werden. Implementierungen dürfen alle verfügbaren Hardware-Ressourcen benutzen,
um shsave/shrestore und store/load-Operationen parallel auszuführen.
-
Shrestore
lädt den
Zustand aller Shreds bedingungslos aus dem Speicher. Dieses Verhalten
ist notwendig, um sicherzustellen, daß der Privatzustand eines Shreds
nicht von einer Task zur nächsten
durchsickert. Shsave kann bedingungslos oder unter Anwendung von
Bedingungen den Zustand aller Shreds aus dem Speicher laden. Eine
Implementierung kann nicht in der Architektur sichtbare Dirty-Bits
beibehalten, um einen Teil der oder die gesamte shsave-Speicheroperation
zu überspringen,
wenn der Privatzustand nicht modifiziert wurde.
-
Die
Instruktionen shsave und shrestore sichern und stellen nur den Privatzustand
des Shreds wieder her. Das Betriebssystem ist dafür verantwortlich,
die gemeinsamen Register 655 zu sichern und wiederherzustellen.
-
Verschieben in/aus gemeinsamen Steuerregistern 660
-
Es
sind Instruktionen zum Beschreiben und Lesen der Shred-Steuerregister
SC0–SC4
660 vorgesehen.
Sie sind im Überblick
wie folgt gestaltet:
mov | r32,
sc0–sc4 |
mov | sc0–sc4, r32 |
-
Die
Instruktionscodierungen sind ähnlich
wie bei den existierenden Instruktionen MOV in/aus Steuerregister 660 und
MOV in/aus Debug-Register. Die Instruktionen MOV in/aus Shred-Steuerregister können auf jeder
Privilegstufe ausgeführt
werden. Es sind Vorsichtsmaßnahmen
vorgesehen, um sicherzustellen, daß bösartige Anwendungsprogramme
keinen anderen Prozeß als
sich selbst durch Beschreiben der Shred-Steuerregister beeinflussen
können.
-
Das
Anwendungsprogramm benutzt eher forkshred und joinshred, als den
Inhalt von SC0 direkt zu manipulieren. Exitmsm kann in atomarer
Weise von Multi-Shred-Modus in Einzel-Shred-Modus übergehen. Mit Hilfe von mov
aus SC0, um den gegenwärtigen
Shred-Ablaufzustand abzulesen, und dann mov in SC0, um einen Shred-Ablaufzustand
zu schreiben, führt
nicht zu den gewünschten
Ergebnissen, da der Shred-Ablaufzustand sich zwischen dem Lesen
und dem Schreiben verändern
kann.
-
Betriebssystemausnahmen
-
MAX
weist mehrere Implikationen für
den IA-32-Ausnahmemechanismus auf. Zunächst ermöglicht ein Ausnahmemechanismus
auf Nutzerebene es, daß mehrere
Typen von Ausnahmen direkt an den Shred gemeldet werden, der sie
erzeugt hat. Dieser Mechanismus ist im folgenden beschrieben.
-
Des
weiteren wird der IA-32-Ausnahmemechanismus modifiziert, um mehrere
Shreds in Gegenwart von Ausnahmen richtig zu bearbeiten, die einen
Kontextwechsel erforderlich machen. Ein Problem des IA-32-Ausnahmemechanismus
des Stands der Technik ist, daß er
dazu definiert ist, CS, EIP, SS, ESP und EFLAGS automatisch für genau
einen ablaufenden Thread zu sichern und wiederherzustellen.
-
Der
existierende IA-32-Ausnahmemechanismus wird erweitert, um die Funktionen
der Instruktionen entermsm, exitmsm, shsave und shrestore zu enthalten.
Wenn ein Interrupt oder eine Ausnahme erzeugt werden, die einen
Kontextwechsel erforderlich machen, tut der Ausnahmemechanismus
folgendes:
- 1) Er beendet den Multi-Shred-Modus
durch Ausführen
von exitmsm. Exitmsm hält
alle Shreds an, bis auf denjenigen, der den Interrupt oder die Ausnahme
verursacht. Das Betriebssystem wird mit Hilfe des Shreds betreten,
der den Interrupt oder die Ausnahme verursacht.
- 2) Er sichert den gesamten aktuellen Zustand des Shreds durch
Ausführen
von shsave an einer Startadresse, die von SC2 vorgegeben wird.
- 3) Er führt
den IA-32-Kontextwechsel durch, wie hier definiert.
-
Um
zu einem Multi-Shred-Programm zurückzukehren, führt eine
modifizierte IRET-Instruktion folgendes durch:
- 1)
Sie führt
den IA-32-Kontextwechsel durch, wie hier definiert.
- 2) Sie stellt den gesamten aktuellen Zustand des Shreds durch
Ausführen
von shrestore an einer Startadresse wieder her, die von SC2 vorgegeben
wird.
- 3) Sie tritt in den Multi-Shred-Modus ein, indem entermsm ausgeführt wird.
Je nach Zustand von SC1 kann die Ausführung von entermsm den Prozessor
dazu veranlassen, im Einzel-Shred-Modus zu verbleiben.
-
Das
Betriebssystem muß einen
Speicherbereich zum Sichern/Wiederherstellen des ShredZustands einrichten,
und seine Adresse in SC2 laden, bevor der IRET durchgeführt wird.
Das Betriebssystem muß auch den
Zustand von SC1, SC3 und SC4 sichern/wiederherstellen.
-
Es
ist möglich,
daß mehrere
Shreds zugleich auf Ausnahmen stoßen, die den Dienst des Betriebssystems
benötigen.
Da die MAX-Architektur nur einen Betriebssystemausnahme zugleich
melden kann, muß die Hardware
Betriebssystemausnahmen für
mehrere Shreds priorisieren, genaue eine melden, und den Zustand aller
anderen Shreds auf den Punkt einstellen, an dem die Instruktion,
welche die Ausnahme erzeugt hat, noch nicht ausgeführt worden
ist.
-
Ausnahme auf Nutzerebene
-
MAX
führt einen
Ausnahmemechanismus auf Nutzerebene ein, der es ermöglicht,
daß bestimmte
Typen von Ausnahmen vollständig
innerhalb des Anwendungsprogramms bearbeitet werden. Es sind keine
Beteiligung des Betriebssystems, Übergänge zwischen Privilegstufen
oder Kontextwechsel nötig.
-
Wenn
eine Ausnahme auf Nutzerebene auftritt, wird der EIP der als nächstes auszuführenden
Instruktionen auf den Stack geschoben, und der Prozessor leitet
an das spezifizierte Steuerungsprogramm weiter. Das Steuerungsprogramm
für Ausnahmen
auf Nutzerebene führt
seine Aufgabe aus und kehrt dann über die existierende RET-Instruktion
zurück.
Gemäß einer
Ausführungsform
ist kein Mechanismus vorgesehen, um Ausnahmen auf Nutzerebene zu
maskieren, da angenommen wird, daß die Anwendung Ausnahmen auf
Nutzerebene nur dann erzeugen wird, wenn die Anwendung dazu bereit
ist, sie zu bedienen.
-
Zwei
Instruktionen sind vorgesehen, um die zweiten zwei Ausnahmen auf
Nutzerebene zu erzeugen: signalshred und forkshred. Diese werden
in den folgenden Abschnitten beschrieben.
-
Signalisierung
-
Die
Instruktion signalshred wird benutzt, um ein Signal an einen spezifizierten
Shred zu senden. Das Format ist:
signalshred | imm16,
target-IP |
signalshred | r16,
target-IP |
-
Der
Ziel-Shred kann entweder als ein Register oder ein unmittelbarer
Operand spezifiziert sein. Die Codierung der Instruktion signalshred
imm16, Ziel-IP ist ähnlich
wie die der existierenden Instruktion Far-Jump, wobei die Shred-Nummer
den 16-Bit-Selektor ersetzt, und die Ziel-IP den 16/32-Bit-Offset
ersetzt. Wie bei Far-Jump ist signalshred Ziel-IP im Verhältnis zu
dem Beginn eines Codesegments (nominell 0) spezifiziert, und nicht
zu der aktuellen IP.
-
In
Reaktion auf signalshred schiebt der Ziel-Shred den EIP der nächsten auszuführenden
Instruktion auf den Stack und leitet an die spezifizierte Adresse
weiter. Ein Shred kann ein Signal an sich selbst senden, wobei die
Auswirkungen dieselben sind wie bei der Ausführung der Instruktion Near-Call.
Wenn der Ziel-Shred nicht abläuft,
wird signalshred stillschweigend ignoriert. Eine #GP(0)-Ausnahme
wird erzeugt, wenn die Shred-Nummer höher ist als die maximale Anzahl
von Shreds, die von der Hardware unterstützt wird.
-
Die
Instruktion signalshred kann auf jeder Privilegstufe ausgeführt werden.
Die Instruktion signalshred leitet keine Parameter automatisch an
den Ziel-Shred weiter. Es ist kein Mechanismus zum Blockieren von
signalshred vorgesehen. So muß die
Software möglicherweise
entweder einen Blockiermechanismus implementieren, bevor sie einen
signalshred ausgibt, oder ein Steuerungsprogramm für signalshred
bereitstellen, das schachteln kann.
-
Shred nicht verfügbar (Shred Not Available – SNA)
-
Forkshred
erzeugt eine #SNA-Ausnahme, wenn das Programm versucht, einen Shred
zu starten, der bereits abläuft.
Ein #SNA-Steuerungsprogramm der Software kann für den existierenden Shred killshred
ausführen
und zu der forkshred-Instruktion zurückkehren.
-
Die
#SNA-Ausnahme wird durch Schieben des EIP der forkshred-Instruktion
auf den Stack und durch Leiten an eine Adresse bearbeitet, die durch
SC4 + 0 vorgegeben wird. Der Code bei SC4 + 0 sollte an das tatsächliche
Steuerungsprogramm abzweigen. Ausnahmevektoren werden an SC4 + 16,
SC4 + 32 usw. angeordnet. Die Software reserviert Speicher bis zu
SC4 + 4095, um 256 mögliche
Ausnahmen auf Nutzerebene abzudecken. Die Interrupt-Tabelle im Speicher/SC4-Mechanismus wird
zu einem späteren
Zeitpunkt durch einen saubereren Mechanismus ersetzt.
-
Aussetzen/Wiederaufnehmen und Shred-Virtualisierung
-
Die
Multi-Thread-Architekturerweiterung erlaubt es Software der Nutzerebene,
Shreds auszusetzen oder wiederaufzunehmen, und zwar unter der Benutzung
der folgenden Instruktionen. So wird ein Shred ausgesetzt:
- 1) Ein Speicherbereich im Speicher wird zum
Sichern des Shred initialisiert. Dies ist ein Speicherbereich, der
von dem Anwendungsprogramm für
die Aussetzaktion eingerichtet wird. Er unterscheidet sich von dem Speicherbereich
für den
Kontextwechsel, der auf SC2 zeigt.
- 2) Ein Signal wird an den Shred gesendet, der auf das Aussetzsteuerprogramm
zeigt. Dies erfolgt über
signalshred Ziel-Shred, Aussetzungssteuerprogramm-IP.
- 3) Das Aussetzungssteuerprogramm sichert unter Benutzung der
existierenden Instruktionen mov, pusha und fxsave den Privatzustand
des Shreds im Speicher.
- 4) Das Aussetzungssteuerprogramm führt einen haltshred durch.
- 5) Der ursprüngliche
Code führt
einen joinshred durch, um zu warten, bis der Shred anhält.
-
Es
ist möglich,
daß der
Shred zum Zeitpunkt der Aussetzaktion bereits anhält. In diesem
Fall wird signalshred ignoriert, das Aussetzungssteuerprogramm wird
nicht aufgerufen, und joinshred wartet nicht. Der Speicherbereich
zum Sichern des Shred behält
seinen Ausgangswert, der auf einen Dummy-Shred zeigen muß, der sofort
einen haltshred ausführt.
Um einen Shred wiederaufzunehmen, werden die umgekehrten Operationen
durchgeführt:
- 1) Aufspalten eines Shred, der auf das Aussetzungssteuerprogramm
zeigt. Dies erfolgt über
forkshred Ziel-Shred, Wiederaufnahme-Steuerungsprogramm-IP;
- 2) Das Wiederaufnahme-Steuerungsprogramm stellt den Privatzustand
des Shreds unter Benutzung der existierenden Instruktionen mov,
popa und fxrestor aus dem Speicher wieder her; und
- 3) Das Wiederaufnahme-Steuerungsprogramm kehrt über die
existierende RET-Instruktion zu dem Shred zurück.
-
Wenn
eine Wiederaufnahme an einem Thread erfolgt, der bereits angehalten
wurde, kehrt das Wiederaufnahme-Steuerungsprogramm zu einem Dummy-Shred
zurück,
der sofort einen haltshred ausführt.
Die Aussetz/Wiederaufnahme-Funktion eröffnet die Möglichkeit der Shred-Virtualisierung.
Bevor ein forkshred durchgeführt
wird, kann sich die Software entscheiden, jeden existierenden Shred
mit derselben Shred-Nummer auszusetzen. Nachdem ein joinshred durchgeführt wurde,
kann die Software entscheiden, jeden existierenden Shred mit derselben
Shred-Nummer wiederaufzunehmen. Da die Aussetz/Wiederaufnahme-Sequenzen
nicht reentrant sind, ist ein Software-kritischer Abschnitt nötig, um
sicherzustellen, daß nur
ein Aussetzen/Wiederaufnehmen für
jeden Shred zu einem jeweiligen Zeitpunkt ausgeführt wird. Mit Hilfe dieser
Mechanismen ist es für
das Anwendungsprogramm möglich,
seinen eigenen präventiven
Shred-Scheduler zu erzeugen.
-
In
alternativen Ausführungsformen
von MAX existiert eine Instruktion zum Aufspalten unter Benutzung des
ersten verfügbaren
Shreds (allocforkshred r32), wobei r32 mit zugeordneter Shred-Nummer
geschrieben ist (bei forkshred spezifiziert r32 die aufzuspaltende
Shred-Nummer). Allocforkshred
gibt auch ein Flag zurück, das
anzeigt, ob verfügbare
Hardware-Shreds
vorhanden sind.
-
In
einer anderen Ausführungsform
stellt eine Warte-Shred-Instruktion eine Wartesynchronisation mit Hilfe
gemeinsamer Register bereit (waitshred sh0–sh7, imm). Die Warteinstruktion
stellt die Wartefunktion als Instruktion bereit. Ohne diese Instruktion
muß eine
Schleife benutzt werden, wie z. B.:
loop: mov eax, sh0
and
eax, mask
jz loop
-
In
einer anderen Ausführungsform
erhält
joinshred eine Bitmaske, um auf mehrere Shreds zu warten. Ohne die
Bitmaske wartet joinshred darauf, daß ein Shred endet. Es werden
mehrere joinshreds benötigt,
um auf mehrere Shreds zu warten.
-
In
einer alternativen Ausführungsform
wird killshred nicht benutzt. Anstelle von killshred kann signalshred,
gefolgt von joinshred, benutzt werden. Das signalshred-Steuerungsprogramm
besteht aus der Instruktion haltshred.
-
In
einer weiteren Ausführungsform
ist es möglich,
forkshred und signalshred zu kombinieren. Forkshred und signalshred
unterscheiden sich in ihrem Verhalten nur in Bezug darauf, ob ein
Shred gegenwärtig abläuft oder
angehalten ist. Wenn es signalshred erlaubt wird, einen angehaltenen
Shred zu starten, kann signalshred potentiell forkshred ersetzen.
-
7 zeigt
ein Ablaufdiagramm eines beispielhaften Prozesses erines Multi-Threadings
auf Nutzerebene gemäß einer
Ausführungsform
der vorliegenden Erfindung. Es wird davon ausgegangen, daß ein Anwendungs-
oder Softwareprogramm den folgenden Prozeß eingeleitet hat. Der folgende
Prozeß wird
nicht im Zusammenhang mit einem bestimmten Programm beschrieben,
sondern statt dessen als Ausführungsform
eines Multi-Threadings auf Nutzerebene, die durch die oben beschriebenen
Instruktionen und Architektur erzielt wird. Außerdem wird der Prozeß zusammen
mit einer ISA eines Mikroprozessors ausgeführt, wie z. B. eines Multiprozessors,
sei es mit einer Architektur von 16, 32, 64, 128 oder mehr Bit.
Ein Multiprozessor (wie z. B. Prozessor 105) initialisiert
Werte in gemeinsamen Registern, z. B. den Registern aus Tabelle
3 oben. (Verarbeitungsblock 705) Prozessor 105 führt eine
forkshred-Instruktion aus, die einen Shred erzeugt. (Verarbeitungsblock 710)
Gleichzeitige Operationen werden von Prozessor 105 durchgeführt. Ein
Haupt-(Mutter)-Shred wird von Prozessor 105 ausgeführt. (Verarbeitungsblock 715)
Die Operation joinshred wird ausgeführt, um darauf zu warten, daß der neue
Ziel-Shred seine Ausführung
abschließt.
(Verarbeitungsblock 730) In der Zwischenzeit initialisiert
der neue Ziel-Shred seinen Stack, ruft eingehende Parameter aus
gemeinsamen Registern und/oder Speicher ab (Verarbeitungsblock 720),
und führt
aus. (Verarbeitungsblock 721) Die Ausführung des aktuellen Ziel-Shreds
wird mit Hilfe der Instruktion haltshred beendet. (Verarbeitungsblock 723)
Der Prozessor 105 gibt Ausführungsergebnisse an das Programm
oder die Anwendung von den Registern zurück, in denen die Ergebnisse
der Ausführung
des Shreds gesichert sind. (Verarbeitungsblock 735) Der
Prozeß ist
abgeschlossen, sobald alle ausgeführten Daten zurückgegeben
wurden. (Abschlußblock 799)
-
Ein
Verfahren und System zum Bereitstellen eines Multi-Threadings auf
Nutzerebene sind offenbart. Obwohl die vorliegenden Ausführungsformen
der Erfindung in Bezug auf spezifische Beispiele und Subsysteme
beschrieben wurden, werden Durchschnittsfachleute verstehen, daß die vorliegenden
Ausführungsformen der
Erfindung nicht auf diese spezifischen Beispiele oder Subsysteme
beschränkt
sind, sondern sich auch auf andere Ausführungsformen erstrecken. Die vorliegenden
Ausführungsformen
der Erfindung umfassen all diese anderen Ausführungsformen, wie in den nachfolgenden
Ansprüchen
spezifiziert.