Neue Architekturen für Mikroprozessoren
Das winzige Bauteil mit vielen Anschlussdrähten, das im Herzen eines Computers die wesentliche Arbeit leistet, wird in den nächsten Jahren eine völlig andere Struktur erhalten. Verschiedene Konzepte sind in der Entwicklung; die Mikroprozessoren der Zukunft sind nicht nur leistungsfähiger, sondern auch vielgestaltiger.
Computerbenutzer neigen dazu, sich im Inneren ihres Gerätes eine handelnde Person vorzustellen: Sie nimmt die Befehle des Benutzers entgegen, stellt gelegentlich Rückfragen ("Wollen Sie diese Datei wirklich löschen?") und scheint zuweilen sehr persönliche Eigenheiten zu haben. Unter Umständen stecken auch mehrere dieser Personen in derselben Maschine und ergreifen abwechselnd das Wort.
Wenn man das Gehäuse eines Computers öffnet, kommen natürlich keine kleinen Männchen heraus. Hinter der – zum Teil sorgfältig konstruierten – Illusion von der handelnden Person steckt ein Programm: eine Folge von sehr vielen Einzelanweisungen. Erst deren Ausführung in ihrer Gesamtheit erweckt den geschilderten Eindruck. Aber wer ist es, der diese Einzelanweisungen ausführt? Eine erste Antwort lautet: der Mikroprozessor, das Herzstück jedes Computers, jenes kleine Bauteil mit den vielen Anschlüssen und Markennamen wie "Pentium" oder "G4".
Und wie funktioniert ein Mikroprozessor, und aus welchen Teilen besteht er? Es ist abermals hilfreich, sich – mit allen gebotenen Vorbehalten – im Inneren des Geräts ein kleines Männchen zu denken, das mit anderen Teilen des Mikroprozessors gewisse Aktionen vollführt.
Der offizielle Name des Männchens ist Leitwerk. Es nimmt eine Anweisung des auszuführenden Programms nach der anderen entgegen und führt sie aus. Typischerweise besteht eine solche Anweisung darin, eine oder zwei Zahlen von einer bestimmten Stelle aus einem großen Regal außerhalb des Mikroprozessors – dem Arbeitsspeicher – zu holen, etwas mit ihnen zu tun, zum Beispiel sie zu addieren oder zu multiplizieren, und das Ergebnis der Aktion an einer bestimmten Stelle im Regal abzulegen. Zum Rechnen steht ihm für jede Grundrechenart ein eigenes Rechenwerk zur Verfügung.
Holen und Weglegen sind, verglichen mit dem Rechnen selbst, relativ zeitraubende Aktionen; zudem muss das Männchen häufig das Ergebnis einer Rechnung im unmittelbar folgenden Schritt weiterverwenden. Zur Zeitersparnis verfügt es deshalb über eine Art Kurzzeitgedächtnis, die so genannten Register. Sie speichern nur relativ wenige Informationen, die allerdings praktisch ohne Zeitverzug. Für die Zwischenlagerung mittelgroßer Datenmengen gibt es noch so etwas wie einen Ablagetisch, den so genannten Cache. Dort finden mehr Daten Platz als in den Registern, die Zugriffszeiten sind etwas länger, aber nicht so lang wie für den Arbeitsspeicher.
Diese klassische Architektur haben die Mikroprozessoren im Wesentlichen noch von den Großrechnern der sechziger und siebziger Jahre übernommen; nur die technische Realisierung der Komponenten hat sich radikal verändert. Noch Anfang der siebziger Jahre bestanden Speicher aus magnetisierbaren Ringen, die von Hand auf die Steuerdrähte gefädelt werden mussten. Mit dem – sprichwörtlich gewordenen – rasanten Fortschritt in der Halbleitertechnik hat nicht nur die Schaltgeschwindigkeit der einzelnen Bauteile um Größenordnungen zugenommen (Kasten rechts); es haben sich auch die Proportionen verschoben. Das ehemals teure Gut Speicherplatz ist inzwischen in großen Mengen verfügbar geworden. Zudem bietet dank der fortgeschrittenen Miniaturisierung ein modernerer Chip bei gleicher Größe und nahezu unverändertem Preis ein Vielfaches an Platz für Bauteile.
Allerdings arbeitet das Männchen nicht schon dadurch schneller, dass es in einem größeren Zimmer sitzt: Es nutzt nicht viel, die Anzahl der Rechenwerke und Register und die Größe des Cache zu erhöhen, wenn das Leitwerk nicht wesentlich mehr Komponenten auf einmal beschäftigen kann als zuvor. Die für den Anwender entscheidende Größe ist die Anzahl an Instruktionen, die der gesamte Chip pro Sekunde ausführen kann. Setzt man allerdings mehrere Männchen in ein Großraumbüro – mehrere Leitwerke auf denselben Chip –, könnten sie sich gegenseitig ins Gehege kommen. Um das Leistungspotential eines "größer gewordenen" Mikroprozessors voll auszunutzen, muss also seine gesamte Architektur neu überdacht werden. Von solchen neuen Konzepten handelt der vorliegende Artikel.
Das noch aus der Zeit der Großrechner überkommene und bis Ende der siebziger Jahre allgemein gültige Grundkonzept für die Zentraleinheit eines Computers heißt Cisc wie complex instruction set computer. Wegen der allgemeinen Knappheit an Speicherplatz waren die Konstrukteure bestrebt, auch den Text eines Maschinenprogramms, der ja im Arbeitsspeicher stehen musste, möglichst kurz zu halten. Deswegen besteht in einem Cisc das Sortiment der Maschinenbefehle aus zahlreichen jeweils sehr inhaltsreichen Instruktionen. Ein einziger Befehl setzt eine ganze Kette von Aktionen in Gang, und zu jeder Aktionskette, die in der Programmierpraxis häufig vorkommt, gibt es einen eigenen Befehl (Kasten Seite 28).
Die Ausführung jedes einzelnen Befehls, ob nun einfach oder komplex, gliedert sich wieder in Einzelschritte, mit deren jedem ein anderer Teil des Prozessors befasst ist. In den Rechnern mit Cisc-Architektur werden diese streng nacheinander ausgeführt. Die Bearbeitung eines Programmbefehls wird erst begonnen, wenn der vorausgegangene Befehl vollständig erledigt ist. Wie ein traditioneller Handwerker macht ein Cisc-Männchen alles selber, und immer schön eins nach dem anderen.
Eine Möglichkeit, den Ablauf der Dinge zu beschleunigen, bietet die Fließbandtechnik (pipelining): Die Komponente, die ihre Arbeit am ersten Befehl getan hat, wendet sich bereits dem zweiten zu, obgleich der erste Befehl bei den nachfolgenden Komponenten noch in Arbeit ist. An die Stelle des Cisc-Männchens tritt eine Kolonne von Fließbandarbeitern, die jeder von einem Befehl nur einen kleinen Teilschritt ausführen – bis hin zu einer merkwürdigen Persönlichkeitsspaltung: Der eine beschäftigt sich damit, zu begreifen, was als nächstes zu tun ist, und sein Nachfolger tut es dann wirklich (Kasten rechts). Damit sich die Befehle nahtlos in das Fließband einreihen, sollte jeder dieselbe Zeit benötigen und aus einer möglichst gleichartigen Folge von Teilschritten bestehen. Das ist bei den mächtigen Befehlen der Cisc-Architektur gerade nicht der Fall.
Risc: schlanker und schneller
Aus diesem Grunde wurden um 1980 die Risc-Architekturen (reduced instruction set computer) konzipiert. Deren Befehlssatz enthält deutlich weniger und einfachere Instruktionen, die sämtlich in einer einheitlichen Grundtaktzeit zu erledigen sind. Dafür werden aus einer Cisc-Instruktion im Allgemeinen mehrere Risc-Befehle (Kasten links). Das kostet für den Programmtext entsprechend mehr Speicherplatz, der aber damals schon reichlich und mit relativ geringer Zugriffszeit zur Verfügung stand.
Mit der Weiterentwicklung der Risc-Architekturen wurden dann aus Effizienzgründen doch auch komplexere Befehle zugelassen, deren Ausführung mehr Zeit als einen Grundtakt benötigt. Das gilt insbesondere für die in der numerischen Mathematik zentralen Operationen mit Gleitkommazahlen: Das Rechnen mit Exponent und Mantisse und das anschließende Zusammenführen der Ergebnisse (Spektrum der Wissenschaft 5/1997, S. 54) sind in einem Grundtakt nicht zu erledigen. Die Standardmikroprozessoren für PCs des Marktführers Intel zerlegen etwa ab dem Prozessor Pentium II intern die komplexen Maschinenbefehle in Folgen einfacherer Befehle, die nach Risc-Prinzipien abgearbeitet werden.
Zusätzlich wurden mehrere Rechenwerke zur gleichzeitigen Ausführung mehrerer Maschinenbefehle in einen Prozessor integriert. Diese "superskalaren" Prozessoren (Kasten Seite 30) sind heute Stand der Technik. Damit hat das Prinzip des Parallelrechners Einzug in die Mikroprozessortechnik gehalten (siehe Spektrum der Wissenschaft, 3/1991, S. 82, 8/1994, S. 16, und 4/1996, S. 62). Anders als bei den Supercomputern, bei denen sich mehrere Prozessoren relativ große Teilstücke einer Aufgabe teilen, geht es hier darum, lauter Einzelbefehle geeignet auf die verschiedenen Funktionseinheiten zu verteilen, und das während der Ausführung des Programms. Man spricht von dynamischer Parallelisierung. Das gedachte Prozessor-Männchen hat viele Hände, die alle unabhängig voneinander und gleichzeitig etwas tun können. Nur ist es nicht einfach, die vielen Hände alle beschäftigt zu halten und damit die potenzielle Leis-tungssteigerung auch auszunutzen. Superskalare Prozessoren erfordern deutlich kompliziertere Leitwerke; dank der Fortschritte der Halbleitertechnik ist dafür inzwischen genügend Platz auf der Chipfläche (Bild Seite 26).
Das derart angewachsene Leitwerk ist weniger einem Männchen mit vielen Händen als vielmehr einem Sklaventreiber vergleichbar, dessen einzige Funktion darin besteht, mehrere untergeordnete Komponenten (die "Sklaven") in Aktion zu halten (Bild rechts). Sein offizieller Name ist "Befehlsgruppierer". Seine Aufgabe ist deswegen so schwierig, weil durch das Aufteilen der Arbeit auf viele Hände zwangsläufig die Befehle nicht genau in der Reihenfolge ausgeführt werden, die das Programm eigentlich vorsieht.
Sklaventreiber und Rechenknechte
Damit trotzdem die Bedeutung des Programms erhalten bleibt, das heißt, unter allen Umständen dasselbe Ergebnis herauskommt wie bei Ausführung streng der Reihe nach, ist der Befehlsgruppierer in seinen Aufteilungsmöglichkeiten eingeschränkt. Wenn Befehl 1 die Adresse berechnet, aus der Befehl 2 seine Daten holen soll (vergleiche Kasten Seite 28), kann der Befehlsgruppierer offensichtlich nicht beide Befehle gleichzeitig ausführen lassen. Stattdessen kann er einem bislang unbeschäftigten Sklaven vielleicht den Befehl 3 erteilen, der eigentlich noch nicht an der Reihe, aber von den beiden anderen unabhängig ist.
Im weiteren Verlauf der Ausführung weist der Befehlsgruppierer diverse Sklaven an, vorzeitig Daten aus dem Arbeitsspeicher in den Cache zu holen oder mit Verspätung aus dem Cache in den Arbeitsspeicher zu räumen; das alles, damit die Rechensklaven bei der Arbeit nicht aufgehalten werden. Dabei muss er darauf achten, dass er nicht zum Beispiel einen längst veralteten Wert, der schon mit einem Wert aus dem Cache hätte überschrieben werden sollen, aus dem Arbeitsspeicher holen lässt. Ein superskalarer Prozessor handelt also wie ein genialer Chaot: Auf seinem überfüllten Schreibtisch findet er ohne Verzug stets die aktuellen Daten, ohne sich mit Aufräumen übermäßig aufzuhalten.
Wenn sich die Gelegenheit ergibt, schickt er ein Zwischenergebnis nicht nur wie üblich an das empfangende Register, sondern zugleich an den Eingang des Rechenwerks, das im unmittelbar folgenden Schritt damit weiterarbeiten soll und sich so das Datenholen sparen kann ("abkürzende Datenpfade").
Häufig kommt es vor, dass die Ausführung des Programms an einer völlig anderen Stelle der Befehlskette fortgesetzt werden soll – oder auch nicht, je nach dem Ergebnis des unmittelbar vorhergehenden Rechenschritts: die so genannte bedingte Verzweigung. Über eine solche Verzweigungsstelle hinaus Befehle vorab ausführen zu lassen erscheint sinnlos; man weiß ja noch gar nicht, ob nicht etwas ganz anderes zu tun ist. Demnach müssten vor einer Verzweigungsstelle alle Sklaven bis auf den, der "die Weiche stellt", die Hände in den Schoß legen und dadurch Zeit vergeuden. Um das zu vermeiden, lässt der Befehlsgruppierer manche Sklaven einfach weiterarbeiten und verwirft ihre Ergebnisse, wenn die Verzweigung in die nicht erwartete Richtung verläuft (spekulative Ausführung).
Wohlgemerkt: All diese Organisationsarbeit leistet der Befehlsgruppierer dynamisch, das heißt zur Ausführungszeit des Programms, indem er die jeweils nächsten zwanzig bis allenfalls fünfzig Befehle nach rein formalen Kriterien analysiert. Einen tieferen Einblick in die logische Struktur des Programms kann er ohnehin nicht gewinnen. Entsprechend sind seine Optimierungsmöglichkeiten begrenzt. Wer sich die Reihenfolge seiner Arbeitsschritte vorher sorgfältig überlegt und sich hinterher nicht mit Datensuchen aufhalten muss, arbeitet eben doch effizienter als ein genialer Chaot.
Der Einblick in die logische Struktur, der dem Befehlsgruppierer fehlt, ist im Prinzip verfügbar, wenn auch auf einer völlig anderen Ebene. Ein Programmierer schreibt ein Programm praktisch nie als Folge elementarer Maschinenbefehle, sondern in einer höheren Programmiersprache wie C oder Java, deren Grammatik der mathematischen Formelsprache und – in sehr bescheidenem Ausmaß – der natürlichen Sprache nachempfunden ist. Dieses Programm in eine Folge von Maschinenbefehlen umzusetzen ist Sache spezieller Programme, der so genannten Compiler.
Aus einem Programm-Urtext ist ein erheblicher Teil der logischen Struktur und der Datenabhängigkeiten mit formalen Mitteln extrahierbar. Ein Compiler arbeitet typischerweise in mehreren Stufen, zu denen die Analyse der Struktur und – an letzter Stelle – die Erzeugung des Maschinencodes gehört.
Schon in der herkömmlichen Mikroprozessortechnik galt es, die Compiler der Hardware auf den Leib zu schreiben, sodass möglichst selten die entstehenden Programme das Fließband anhalten oder Datenabhängigkeiten überlappende Ausführung verhindern. Diese Synergie wird nun auf höherer Ebene fortgesetzt. Damit übernimmt die Software die Rolle des Sklaventreibers, allerdings zu einem viel früheren Zeitpunkt, nämlich bei der Kompilierung.
In der Praxis wird daher ein neuer Mikroprozessor nur so gut sein wie die für ihn geschriebenen Compiler. Das ist nicht unproblematisch, weil diese in ihrer Entwicklung im Allgemeinen der Hardware erheblich nachhinken.
Drei neue Konzepte werden derzeit entwickelt:
- statische Parallelisierung,
- vielfädige Ausführung sowie
- der Netzwerkprozessor.
Bei den beiden ersten Konzepten ist es der Compiler, der sich gewissermaßen vorher überlegen muss, wie er die anfallende Arbeit auf mehrere Teilprozessoren verteilt – eben so, dass sie unabhängig voneinander arbeiten können. Bei der statischen Parallelisierung, auch "explizite Parallelisierung" genannt, erzeugt der Codegenerierer – die letzte Stufe des Compilers – "breite Befehle" (VLIW wie very long instruction word). Das sind Sammelanweisungen – eine für jedes Rechenwerk. Dabei berücksichtigt der Compiler die Eigenschaften des Programms und der Architektur, sodass die ursprüngliche Bedeutung des Programms erhalten bleibt und zugleich Datenabhängigkeiten den Betrieb nicht mehr als unvermeidlich aufhalten.
Die Technik der statischen Parallelisierung hat viele Vorteile:
- Der Größe einer umzusortierenden Befehlsfolge sind im Prinzip keine Grenzen gesetzt; es darf theoretisch das ganze Programm sein, und je größer, desto mehr Möglichkeiten gibt es für die Optimierung. Leider ist das Problem, die beste Reihenfolge zu finden, NP-vollständig – wie alle interessanten Optimierungsprobleme in der Informatik; das heißt, das Optimum findet sich nur mit exponentiellem Aufwand (vergleiche Spektrum der Wissenschaft, 4/1999, S. 76). Es gibt jedoch gute heuristische Verfahren (Kasten Seite 32).
- Der Zeitaufwand für die Optimierung muss nicht jedes Mal während der Ausführung des Programms erbracht werden, sondern nur einmal während der Übersetzung. Der Anwender erhält also ein schnelleres Programm als im Falle der dynamischen Parallelisierung.
- Die Steuerlogik für die parallele Arbeitsweise der Rechenwerke im Prozessor wird deutlich vereinfacht und erfordert entsprechend weniger Chipfläche. Der dadurch frei werdende Platz ist für zusätzliche Rechenwerke und größere Cachespeicher nutzbar.
Statische Parallelisierung: gut geplant, aber wenig flexibel
Diesen Vorteilen stehen Nachteile gegenüber, die sich alle aus dem frühen Zeitpunkt der Optimierung ergeben: Wenn der Chip, auf dem das Programm läuft, mehr Rechenwerke hat, als der Compiler eingeplant hatte, bleibt diese zusätzliche Leistungsfähigkeit ungenutzt; im umgekehrten Fall läuft das Programm überhaupt nicht. Statische Parallelisierung kann nicht viel ausrichten, wenn das Programm viele bedingte Verzweigungen enthält.
Eine weitere Programmiertechnik widersetzt sich hartnäckig der Optimierung durch den Compiler: die so genannten Zeigerstrukturen. Der Prozessor findet unter einer Adresse nicht die Zahl, die er braucht, sondern eine weitere Adresse, also einen Verweis oder "Zeiger" (pointer) auf einen anderen Speicherplatz, unter dieser Adresse noch eine und so weiter; er muss also gewissermaßen von Pontius zu Pilatus rennen, bis er seine Zahl endlich hat – mit einer unbestimmten Anzahl von Stationen.
Der Hauptnachteil der statischen Parallelisierung – in der gegenwärtigen Situation – liegt jedoch in der Unverträglichkeit von altem und neuem Konzept: Maschinenbefehle für superskalare Prozessoren können auf VLIW-Prozessoren nicht ausgeführt werden. Alle Programme, die auf den neuen Chips laufen sollen, müssten also neu kompiliert werden. Ersatzweise muss man den VLIW-Prozessor – aus historischen Gründen! – mit einem zusätzlichen superskalaren Prozessor ausstatten oder mit einer speziellen Hardware, die herkömmliche Befehle in VLIW-Instruktionen übersetzt (binäre Compilation). Beide Möglichkeiten kosten Chipfläche und Ausführungszeit.
Darin liegt das Hauptrisiko für die Mikroprozessorhersteller Intel und HP, die gemeinsam in diesen Wochen eine VLIW-Architektur auf den Markt bringen. Es handelt sich um den Itanium-Prozessor (früherer Codename Merced) mit dem neuen Befehlssatz IA-64. Der neue Prozessor wird zunächst neun Rechenwerke haben, von denen bis zu sechs gleichzeitig nutzbar sind.
Der jüngst von der Firma Transmeta vorgestellte Crusoe-Prozessor verwandelt durch binäre Compilation (die bei Transmeta "Code morphing" heißt und teils durch Hardware, teils durch Software durchgeführt wird) den Maschinencode X 86 von Intel in VLIW-Instruktionen.
Jeder Prozessor spinnt sein Fädchen
Eine Parallelisierung auf höherer Ebene, die im Prinzip mit den bisher beschriebenen Techniken verknüpfbar ist, verfolgt der Ansatz der vielfädigen Architekturen (multithreaded architectures). Die Idee ist, dass das Programm durch den Compiler oder den Programmierer in mehrere gleichzeitig ausführbare Teilprogramme zerlegt wird. Diese Teile heißen Fäden (threads); der Begriff soll andeuten, dass jeder von mehreren Teilprozessoren an seinem Faden arbeiten kann, ohne die anderen zu stören oder von ihnen gestört zu werden, andererseits auch, dass jeder einzelne Faden leichtgewichtig ist: Es erfordert nicht viel Aufwand, wenn ein Prozessor den Faden weglegt und ein anderer ihn wieder aufgreift (Bild rechts).
Alle Fäden eines Programms dürfen im Prinzip auf dieselben Daten im Hauptspeicher zugreifen; der Compiler hat dafür zu sorgen, dass nicht durch den konkurrierenden Zugriff mehrerer Fäden, die ihre Aktivität nicht synchronisieren, veraltete Daten aus dem Speicher geholt oder noch benötigte überschrieben werden. Neben diesen gemeinsamen Daten gibt es noch Informationen, die jeder Faden für sich behalten muss: an welcher Stelle des Programms sich die Ausführung gerade befindet, die wievielte Runde eines mehrfach auszuführenden Programmteils gerade stattfindet, ob der Faden gerade auf Dateneingabe wartet, ob ein Fehler aufgetreten ist und ähnliches. Leichtgewichtigkeit bedeutet, dass die Menge dieser durch das Betriebssys-tem zu verwaltenden Zustandsinformationen klein ist.
Zur Laufzeit des Programms weist das Betriebssystem des Prozessors den einzelnen Teilprozessoren ganze Fäden zur Bearbeitung zu. Dank dieser Technik ist die Parallelisierung unproblematisch und ihr Potenzial nicht begrenzt. Es ist auch nichts dagegen einzuwenden, dass Fäden verschiedener Programme parallel nebeneinander her arbeiten. Wenn sich schon die Fäden eines einzigen Programms gegenseitig nicht stören, gilt das erst recht für Teilprozesse, die ohnehin nichts miteinander zu tun haben.
Prozessoren für vielfädige Architektur enthalten spezielle Speicherplätze, in denen die Kontextinformationen aller aktiven (rechnenden oder zum Rechnen Schlange stehenden) Fäden stehen. Das erleichtert es den Prozessoren oder Rechenwerken, von einem Faden auf den anderen zu wechseln. Jeder Faden hat einen eigenen Registersatz; der Prozessor muss sich also, bevor er ein Ergebnis in einem Register ablegt, sozusagen vergewissern, welchen Faden er gerade bearbeitet. Die Zeit dafür kann verkürzt werden, indem die erforderliche Information in den Daten mitgeführt wird. Zukünftige Versionen des Mikroprozessors Alpha der Firma Compaq (Dec) werden diese Technik etwa ab 2004 verwenden.
Chips mit angeborener Netzwerkfähigkeit
Der Netzwerkprozessor als Kern eines Netzwerkcomputers ist ganz auf die Nutzung des 1991 eingeführten World Wide Web optimiert. Er zielt darauf ab, die Gesamtkosten für die Nutzung von Computern dadurch zu verringern, dass der einzelne Anwender nicht Eigner aller Programme und Rechnerressourcen ist, sondern diese bei Bedarf über das Web, gegebenenfalls gegen Nutzungsgebühr, bezieht.
Im Gegensatz zu klassischen Rechnern, bei denen das Betriebssystem verschiedene Programmteile, die gemeinsam zur Ausführung kommen sollen, zuerst zusammenbindet und dann das Gesamtprogramm startet, soll der Netzwerkprozessor fehlende Programmteile zur Laufzeit im Internet suchen, heranschaffen und anwenden. Dieser sehr komplexe so genannte Resolutionsprozess, zu dem außerdem die Überprüfung von Rechten und der Korrektheit der Übertragung gehört, ist Teil der Maschinenbefehle. ("Resolution" bedeutet in diesem Zusammenhang Auflösung, nämlich des Rätsels, wo wohl das angeforderte Unterprogramm zu finden sei.)
Den Netzwerkprozessor gab es zunächst nur auf dem Papier, als "virtuelle Maschine": Festgelegt wurde nur der Maschinenbefehlssatz, die Realisierung konnte später kommen – ob in Hardware oder in Software, blieb offen. Zur Definition der objektorientierten, auf die Nutzung des WWW ausgelegten Programmiersprache Java (Spektrum der Wissenschaft, 7/1996, S. 17) gehört eine solche virtuelle Maschine, die Java Virtual Machine (JVM).
Der Java-Maschinencode ("Bytecode") ist auf Rechnern verschiedenster Hersteller ausführbar, wenn diese nur die virtuelle Maschine realisiert haben. Dazu kann man entweder jeden JVM-Maschinenbefehl mittels spezieller Software in eine Befehlsfolge für einen konventionellen Prozessor umwandeln lassen oder spezielle Hardware konstruieren, die JVM-Befehle direkt ausführt. Beides ist bereits geschehen, nachdem die Firma Sun die Programmiersprache Java und die zugehörige virtuelle Maschine definiert hatte. Software-Realisierungen sind im allgemeinen sehr viel langsamer (um einen Faktor 10 bis 100) als eine Hardware-Implementierung. Diese ist allerdings aufwendig und teuer, weil die Befehle der JVM – schon wegen des Resolutionsprozesses – extrem komplex sind.
Damit verläuft die Entwicklung des Netzwerkcomputers genau in die Gegenrichtung zur bisherigen Tendenz. Während das Risc-Konzept und die statische Parallelisierung Komplexität von der Hardware in die Software geschoben hatten, zielt die JVM auf eine komplexere (virtuelle) Maschine, um einfachere und insbesondere portable Software zu ermöglichen. Welche der beiden Richtungen sich langfristig durchsetzen kann, wird letztlich die Flexibilität der Ansätze entscheiden. Die Kosten für die Entwicklung neuer Mikroprozessoren mit mehreren Millionen Transistorfunktionen sind nämlich inzwischen so hoch, dass sie sich nur über Stückzahlen in der Größenordnung mehrerer Millionen amortisieren.
Sowohl VLIW-Prozessoren als auch der Netzwerkprozessor haben Befehlssätze, die zu den heute gängigen nicht kompatibel sind. Um diesen Nachteil zu umgehen und trotzdem weitere Leistungssteigerung auf einem Chip zu erzielen, bauen andere Hersteller (zum Beispiel IBM und AMD) Chips, die mehrere komplette Prozessoren enthalten. Die Parallelisierung muss dann auf höherer Ebene, also für ganze Programme oder Programmteile erfolgen.
Insgesamt ist zu erwarten, dass der Markt der Mikroprozessoren nicht einheitlicher, sondern bunter wird.
Literaturhinweise
Prozessoren. Von Arndt Bode in:
Informatik-Handbuch, Von Peter Rechenberg und Gustav Pomberger (Hg.). Hanser, München 19992,
S. 293–322.
Processor Architecture. From Data-flow to Superscalar and Beyond. Von Jurij Silc, Borut Robic und Theo
Ungerer. Springer, Berlin 1999.
Aus: Spektrum der Wissenschaft 5 / 2000, Seite 26
© Spektrum der Wissenschaft Verlagsgesellschaft mbH
Schreiben Sie uns!
Beitrag schreiben