Home Computer Hardware Site Map counter

Die Entwicklung von Rechnerarchitekturen

Einleitung

Heute sind Prozessoren ganz schön komplex, mit allerlei Features. Das alles erschwert aber das Verständnis der Funktionsweise eines Prozessors. In diesem Beitrag soll gezeigt werden, wie sich die Prozessorarchitektur seit den 8 Bit Tagen entwickelt hat. Dabei geht es um die Erklärung der hübschen technischen Begriffe wie "Trace Execution Cache", nicht darum ob nun Prozessor × oder y der bessere sei. Ich habe mich in der Baureihe auf die Intel Prozessoren des X86 Serie gestützt, da ich diese sehr gut intern kenne, es sind aber auch verweise auf andere Architekturen enthalten, sofern diese angebracht sind. (Hinweis: dieser Artikel stammt aus dem Jahr 2000)

Die Grundeinheiten eines Prozessors am Beispiel eines 8 Bitters

Sinn macht es die Funktionsweise evolutionär zu betrachten, das heißt ausgehend von einem 8 Bit Mikroprozessor, wie er 1974-1980 Stand der Technik war die Weiterentwicklung zu untersuchen. Jeder Prozessor besteht aus mehreren Funktionseinheiten die sich seit den 8 Bit Tagen des 8080 gehalten haben:

  1. Adressbus: Von seiner Breite hängt ab wie viel RAM ansprechbar ist. Bei einem 8 Bitter waren es 16 Adressleitungen wodurch 64 Kilobyte RAM adressierbar waren, bei den folgenden 16 Bittern je nach Typ 16,20 oder 24 Bit, also maximal 16 MByte und bei den aktuellen 32 Bittern sind es 32 Bit. Bei dem Laden von Daten oder Code legt der Prozessor die Gewünschte Adresse von wo die Daten kommen sollen auf den Adressbus und holt die Daten über den Datenbus.
  2. Der Datenbus dient dem Transfer von Daten vom Speicher zum Prozessor und zurück. Leider sagt die Breite des Datenbusses überhaupt nichts über die Verarbeitungsbreite des Prozessors aus, sondern nur wie viel Bytes auf einmal transportiert werden. Insbesondere Intel war sehr erfinderisch bei der Einführung von Prozessoren mit künstlich verkleinertem Datenbus. Allgemein gilt aber: je größer der Datenbus desto schneller der Prozessor. Deswegen verfügen 32 Bit Prozessoren von Intel seit dem Pentium über einen 64 Bit Datenbus, der Datenbus ist hier also größer als die Verarbeitungsbreite des Prozessors. Ein großer Datenbus erlaubt es bei einer gegebenen Speichergeschwindigkeit (die heute viel langsamer ist als die Prozessoren Daten holen könnten) mehr Daten zu holen indem man auf einmal 8 Bytes aus 8 Speicherchips holt.
  3. Steuerbus: Kein Prozessor ist alleine, in der Regel hat man an Ihn weitere Bausteine oder ganze Peripheriesysteme angeschlossen. Auch mit diesen muss der Prozessor Daten austauschen können. Dies geschieht über einen eigenen Steuerbus. Da dieser zusätzliche Leitungen benötigt versucht man ihn bei vielen Prozessoren einfach zu halten. Bei Intel Prozessoren geschieht das Anlegen der Portadresse über den normalen Adressbus, nur eine zusätzliche Leitung zeigt an, das diesmal Steuersignale gemeint sind. Bei anderen Prozessoren wird sogar komplett auf einen eigenen Steuerbus verzichtet und der Prozessor spricht Bausteine über normale Speicheradressen an, auf diesen Bereichen kann dann kein Speicher eingebaut werden.
  4. Recheneinheit: Jeder Prozessor hat mindestens eine Recheneinheit die meistens als ALU (Arithmetisch / Logische Unit) abgekürzt wird, und die Ganzzahlrechnungen und logische Berechnungen durchführt. Bei modernen Prozessoren können hier mehrere dieser Einheiten vorliegen.
  5. Steuereinheit: Sie sorgt für die gesamten Abläufe im Prozessor: Dekodiert die einkommenden Daten um festzustellen welche Befehle sie enthalten, regelt die interne Kommunikation und erhöht die Adressen nach dem Programm
  6. Register: Register sind Zwischenspeicher auf dem Prozessor zur Speicherung von Rechenergebnissen aber auch zum Rechnen. Neben den Registern die man als Programmierer benutzen kann, gibt es oft weitere die man direkt nicht bearbeiten kann wie den Programmzähler (welche Adresse wird momentan ausgeführt) oder den Stackpointer der einen Zwischenspeicher verwaltet. Im allgemeinen kann man von Registern nie genug haben, doch dazu mehr im folgenden Absatz

Der Maschinenzyklus

In der grauen Computervorzeit (den sechziger und siebziger Jahren) hat man die Leistung eines Computer in Maschinenzyklen gemessen. Dieser Wert ist heute nicht mehr so von Belang, doch er ist wesentlich für das Verstehen der Funktionsweise eines Prozessors.

Die Ausführung eines Befehles geht nicht in einem Rutsch, sondern es sind mindestens 4 Phasen notwendig, die sich je nach Befehl in weitere Unterphasen aufteilen lassen.

Jeder Schritt benötigt einen Takt, so das ein Maschinenzyklus bei den meisten Prozessoren mindestens 3 Takte erfordert. Eine der Ziele bei der Prozessorentwicklung war es diese Zahl der Takte zu senken.

Maschinensprache und Register

Intel 8080 Prozessor Jeder Prozessor hat eine Anzahl sehr einfacher Befehle die typisch für ihn sind und nicht auf andere Prozessoren übertragbar. So gibt es nicht eine Maschinensprache sondern eine für Power PC, eine für Pentium und eine für Alpha Prozessoren.

Verknüpft ist diese Maschinensprache mit der Architektur des Prozessors und diese spiegelt sich auch in den Registern wieder. Stellen wir uns vor, wie würden einen neuen 16 Bit Prozessor bauen der 16 MB (24 Bit) Adressieren kann. So ein Prozessor hat typischerweise um die 60-200 Maschinenbefehle. Nehmen wir mal an es wären 64. Diese könnten wir bequem in einem Byte dekodieren, das ja 256 Zustände einnehmen kann. Doch so einfach ist es nicht. Viele Befehle benötigen einen oder sogar zwei Operanden. Hier ein Beispiel:

Wir stellen schnell fest, bei nur einem Register gibt es für jeden Befehl schon 3 Möglichkeiten die ein Operand haben kann: Ein Register, eine Konstante und eine Adresse. Bei Zwei Operanden sind es schon 6 Kombinationsmöglichkeiten. Damit vervielfältigt sich die Anzahl der Befehle.

Selbst wenn nicht alle Befehle Operanden haben, und man nicht alle Kombinationen zulässt gibt es ohne Probleme bei 3 oder 4 Registern - und dass ist nicht gerade viel - schon mehr Kombinationsmöglichkeiten als in ein Byte hineinpassen. Man benötigt also dann zwei Bytes für einen Befehl. Damit wird zum einen der Code länger, zum anderen dauert das Dekodieren von 2 Byte natürlich länger als von einem Byte.

Es gibt nun zwei Ansätze dieses Dilemma zu lösen. Beim CISC Ansatz (Complex Instruction Set Computer) versucht man mit weniger Registern auszukommen dafür mächtige Befehle zu benutzen und oft spezialisierte Register. Es gibt dies schon bei 8 Bittern wie dem Z80 der mit einem Befehl einen ganzen Speicherblock verschieben kann. Auch der 8086 und seine Nachfolger haben nur wenige freie allgemein nutzbare Register (AX,BX,CX und DX) die spezialisiert sind. Selten gebrauchte Operationen versucht man in 2 Byte zu kodieren, die häufigen dagegen in einem. Die Länge des Codes ist damit variabel und schwankte schon bei einem 8 Bit System zwischen einem und 5 Byte.

Bei RISC sagt man sich dagegen: In Ordnung, ich kann nicht alle Befehle in einem Byte kodieren, dann versuche ich wenigstens die Möglichkeiten mit 2 Byte voll auszunützen indem ich das zusätzliche Byte nutze um erheblich mehr Register anzusprechen. RISC Prozessoren haben daher oft sehr viele Register auf dem Chip - 32,64 oder gar 128 und alle sind gleichberechtigt. Es gibt nur die einfacheren Maschinenbefehle, nicht die Superbefehle von CISC. Den Nachteil von längerem Code versucht man mit einem einheitlichen Format zu begegnen. Bei unserem Papierprozessor z.B. könnte man sagen: Alle Befehle die mit Werten oder Adressen zu tun haben werden in einem Byte kodiert, die nächsten 3 Byte entfallen dann auf die Adresse/Daten und alle anderen Befehle werden in 2 Byte kodiert, dann entfallen die Bytes 3 und 4 auf jeweils die Nummer von einem von 256 Registern. Alle Befehle wären dann 32 Bits lang und man könnte 256 Register nutzen. Dafür verschwendet man Platz, denn bei CISC gibt es variable Befehlslängen, z.B. benötigt nicht jeder Befehle zwei Operanden, so das bei manchen Befehlen das 4 Byte oft unbenutzt wäre.

RISC entstand Mitte der achtziger Jahre als Bewegung aus zahlreichen Universitätsinstituten heraus und wurde von Hardwareherstellern aufgegriffen welche die Chance sahen in der Geschwindigkeit mit den Intel Prozessoren mitzuhalten, ohne über die finanziellen Mittel zur Verfügen um die gleichen Komplexen Prozessoren zu fertigen. Mehr über RISC und CISC in einem eigenen Aufsatz.

Anleihen für Hochsprachen

Ein lange gehegter Traum ist es einen Prozessor zu haben der direkt in einer Hochsprache programmiert werden kann. Vereinzelt gab es auch Projekte wie einen LISP Prozessor der LISP als "Assembler" verstand, doch in der Regel befand man das eine Hochsprache zu komplex wäre und man für zahlreiche "niedrige" Systemaufgaben trotzdem Assembler brauchte.

Schon immer inspirierten sich beide Konzepte: C entstand als hardwarenahe Programmiersprache und beherrscht eigentlich nur die grundlegenden Datentypen des Prozessors. Andererseits wurde der heute in allen Prozessoren anzutreffende Stack wurde zum ersten mal in den sechzigern von Wirth für seine virtuelle Pascal Maschine eingeführt und von den Prozessoren erst später übernommen. Vor allem bei den Datentypen nähern sich die Konzepte an: Anders als ein Prozessor gibt es bei Hochsprachen z.B. verschiedene Datentypen die ein Prozessor nicht kennt :

Zur Unterstützung dessen wurden in vielen Prozessoren Maschinenbefehle eingeführt. So beherrschte bitweise Datenmanipulation z.B. der Z80 mit Befehlen um Bits zu setzen, rückzusetzen oder abzufragen. Da die meisten Programme diese selten benutzten und es oft aus Performancegründen geschickter war Speicher zu verschwenden und ein Byte pro Bit zu verwenden verschwanden diese Befehle allerdings rasch wieder.

Fast alle Prozessoren führten jedoch einen Indexzugriff auf den Speicher ein, meistens mit einem Register als Basisadresse und einem zweiten Register als Offset. Durch erhöhen dieses Offsets in festen Werten konnte man so leicht über ein Array iterieren. Diese Zugriffsmethode ist heute Standard

Auch für Strings gab es eigene Befehle. Die 80x86 Serie kann z.B. mit einigen Befehlen einen String kopieren, eine Subposition eines Zeichen finden oder zwei Strings vergleichen. Bei vielen RISC Prozessoren findet man aber nicht diese Hochspezialisierten Befehle

Funktionsaufrufe in Hochsprachen laufen üblicherweise über den Stack ab: Ein Speicherbereich auf den Register abgelegt werden wobei man immer nur am Ende ein Register sichern (PUSH) oder eines lesen (POP) kann. So werden Argumente an die Funktion auf dem Stack abgelegt und dann von diesem wieder von der Funktion geholt und eventuell Ergebnisse wieder dort abgelegt. Der Stack liegt aber nicht im Prozessor sondern im Hauptspeicher und so ist diese Vorgehensweise sehr zeitaufwendig, weshalb einige Sprachen wie C/C++ mit Makros arbeiten - Codeschnipsel die eingefügt werden und Funktionen ersetzen.

Beim SPARC Prozessor wurde zum ersten Mal das Register Windows eingeführt: Der sehr große Registersatz setzt sich aus immer sichtbaren Registern zusammen und einem Satz von 16 Registern die gewechselt werden können: Beim Aufruf einer Funktion muss nur dieser Kontext gewechselt werden, wobei dies im Prozessor erfolgt und sehr schnell ist. Der Stack ist für Argumente nicht mehr nötig. Diese Technik wurde in Folge auch von anderen Prozessoren übernommen.

Der Speicher und warum er das Prozessordesign so komplex macht

Als die 8 Bitter entwickelt wurden war die Welt noch in Ordnung: Man musste sich nicht um die Geschwindigkeit des Speichers kümmern, er war schneller als der Prozessor. Die ersten 8 Bitter arbeiteten mit 1-2.5 MHz und Speicher hatte Zugriffszeiten von 250 ns, ausreichend also für 4 MHz (4 * Taktfrequenz = Speichertakt in ns). Auch als spätere 8 Bitter bis zu 8 MHz erreichten war das kein Problem, inzwischen gab es Speicher mit 120 ns Zugriffszeit. So betrug bei den Prozessoren der achtziger Reihe (8080,8085 und Z80), z.B. die Ausführungszeit eines Befehls mindestens 4 Takten - dies entspricht einem Speicherzyklus.

Doch schon bei den 16 Bittern war's aus mit diesem einfachen Leben, es kamen die ersten Entwicklungen auf die es erlaubten die Taktfrequenz des Prozessors über dem des Speichers zu setzen. Diese Notwendigkeit ergab sich einfach aus den steigenden Taktfrequenzen. 1978 erschien der 8086 mit 5 MHz, die Taktfrequenz stieg zuerst nur langsam an und erreichte bis 1982 8 MHz beim 80286, doch dann begannen die Taktfrequenzen schnell zu steigen: 1985 16 MHz, 1989 33 MHz, 1993 66 MHz... Eine Verdopplung alle 3 Jahre. (Seither noch schneller, von 1998 bis 2001 stiegt die Taktfrequenz von 500 auf 2000 MHz, also um das 4 fache in 3 Jahren).

Doch Speicherchips konnten nicht so schnell gesteigert werden, bis zum Einführung von SD-RAM 1996 stieg innerhalb von 20 Jahren die Zugriffszeit von Speicher von 250 ns auf 60 ns, also um den Faktor 4. Die Taktfrequenz von Prozessoren dagegen von 2.5 MHz auf 200 MHz also um den Faktor 80! Neben dem Konzept des Caches und Prefetches kann man Speicher eigentlich nur durch Banks schneller machen. Dieses Konzept ist nicht neu: Schon bei der Cray 2 hat man einen Rechner mit hoher Taktfrequenz so an Speicher mit langsamer Zykluszeit angeschlossen. Das Konzept ist folgendes: Anstatt einem Speicher nimmt man z.B. 4 Speicherbänke die je ein Viertel des Speichers abdecken. Intelligenterweise verschiebt man diese so, das man folgenden Zugriff hat:

Adresse Bank Takt
4711 0 1
4712 1 2
4713 2 3
4714 3 4
4715 0 5

Wenn man also Code in die CPU holt greift man nacheinander auf alle Bänke zu - in der Regel springt man bei Programmen nicht wild in der Gegend herum sondern arbeitet zumindest einige Befehle linear oder wiederholt in einer Schleife ab. Bei diesem Konzept mit 4 Banks greift also der Prozessor bei jedem 4.ten Takt erst wieder auf denselben Speicher zu. Dieses Konzept wird durch Sprünge, Zugriff auf Daten (die nicht immer ideal liegen müssen) oder Unterprogrammaufrufe allerdings durchkreuzt, in diesem Fall muss der Prozessor warten, wofür sich schon bald den Ausdruck "Wait State" einbürgerte.

Prefetch

Intel 8086/88 Schon beim 8086/88, dem ersten 16 Bitter von Intel wurde daher eine Technik eingeführt um den Prozessor vom Speicher etwas unabhängiger zu machen. Das erste war, das Bus und Ausführungseinheit voneinander getrennt waren. Beim 8086 waren die Befehle daher nicht mehr ein Vielfaches von 4 Takten, denn wenn nur Daten geholt wurden, hatte die Ausführungseinheit bisher nichts zu tun. Nun konnte sie schon an das Dekodieren gehen, während zugehörige Operanden erst aus dem Speicher geholt wurden. Dazu diente auch ein kleiner Zwischenspeicher die Prefetch Queue. Diese Technik wurde in der Folge verbessert. Heute läuft ohne Prefetch nichts mehr. Eine Prefetch Queue ist im einfachsten Fall nur ein kleiner Zwischenspeicher der einfach nur linear Bytes vom Speicher holt. Arbeitet der Prozessor zum Beispiel bei Adresse 4048, so holt der Prozessor einfach schon mal die Bytes 4049,4050,4051... Da Programme normalerweise linear abgearbeitet werden ist das auch sinnvoll. Wenn allerdings der Prozessor Daten braucht die etwas weiter entfernt sind oder eine Verzweigung im Code kommt, dann nützt dieser Zwischenspeicher nichts und es dauert länger ihn wieder neu zu füllen, als wenn man direkt auf den Speicher zugreift. Im Mittel gibt es jedoch einen deutlichen Performancegewinn.

Weiterhin dauerte das Schreiben auf den Speicher länger als das Lesen, außerdem haben Hochsprachenprogramme sehr oft Befehle bei denen die Daten geholt werden, die gerade erst gespeichert wurden. Damit der 8086 nun nicht die veralteten Daten aus der Prefetch-Qeue holte hatte er einen kleinen Schreibpuffer. Die heutigen SD-RAM's haben eine ähnliches Prinzip um die "niedrigen" Zugriffszeiten zu erreichen: Wenn der Rechner Daten haben will, so braucht dies genauso lang wie bei normalen EDO-RAM's, also etwa 55 ns. Danach liefert SD-RAM die nächsten 8 Bytes in schneller Folge nach, da er vorschauend diese schon ausliest - nun in erheblich kürzerer Zeit von 7-10 ns. Braucht der Prozessor diese aber nicht oder wechselt er aus anderen Gründen die Adresse, so ist SD-RAM wieder bei dem langsamen 55 ns Erstzugriff. Das ist auch der Grund warum die Übergänge in den Architekturen (EDO-RAM -> SD RAM -> DDR RAM und das Hochfahren der Taktzeiten für diesen "Burst" Modus so wenig auf die Anwendungen durchschlagen - Im Mittel kommt z.B. von 100 % mehr Daten bei DDR RAM noch 36 % an, wenn man die Zugriffszeit vor dem Burst dazurechnet. Anwendungen werden sogar nur um 10-20 % schneller.

Eine Lösung ist für das Problem derzeit nicht in Sicht. Man kann nur versuchen das Zugriffsverhalten zu optimieren (siehe auch zum Cache) weiter unten. Evt. übernimmt man Anleihen von den Grafikchipsätzen die sehr stark auf schnelles RAM angewiesen sind. Neben sehr schnellem RAM findet man dort auch bis zu 256 Bit breiten Busse und die Chips sind fest eingelötet anstatt über Module mit langen Leitungswegen und kapazitiven Widerständen angebracht. Dadurch werden Bandbreiten bis 20 GB/s erreicht, während im PC Bereich zum Zeitpunkt des Artikels bei 2.7 GB/s Schluss ist. Angesichts sinkender Preise und immer kürzeren Zyklen bei neuen Mainboards, könnte fest eingelöteter Speicher mit besserer Zugriffszeit, zumindest für bestimmte Anwendungsgebiete interessant erscheinen.

Cache

Intel 80286 Der 80286 verfügte um erheblich längere Prefetch Queues und größere Schreibpuffer. Die Performancesteigerung gelang vor allem aber durch schnellere Befehlsausführung. Mit dem 386 kam nun eine erhebliche Änderung im Aufbau des Prozessors. Er wurde zu einem 32 Bit Prozessor, doch dazu später mehr. Der 386 war aber vor allem der erste Prozessor der erheblich schneller als das RAM war. Damit nun der 386 überhaupt schneller als ein 286 war, musste man dies ausgleichen können und führte das Konzept des Caches ein. Damals war er noch separat auf dem Motherboard untergebracht. Der Prozessor selbst greift zuerst auf den Cache zu. Dieser speichert den Code vom Hauptspeicher zwischen und hat eine Zugriffszeit die den Prozessor nicht ausbremst. Der Cache wird von einem Teil des Prozessors, dem Cachecontroller verwaltet. Er bündelt jeweils 16 oder 32 Bytes zu einer "Cacheline". Wenn der Prozessor neue Daten braucht die nicht im Cache stehen so muss der Cachecontroller diese vom Hauptspeicher laden. Dazu muss er entscheiden welche Cachelines am längsten nicht benutzt wurden. Dazu hat er eine Indextabelle an der jeweils steht welche Cacheline zu welcher Adresse gehört.

Heute ist der Cache nicht mehr direkt gemappt, sondern man speichert für eine Indexadresse mehrere Cachelines ab. Man nennt das mehrfach assoziativ. Ein grundsätzliches Problem ist allerdings das man nun entscheiden muss welche Cacheline verworfen werden muss. Dazu hat ein Prozessor heute eine ausgeklügelte Logik an Bord die den LRU (Least Recently Used) Eintrag herausfindet. Auch beim Schreiben landen die Daten zuerst im Cache, außer die Adresse ist außerhalb des Cache Bereiches. Dann spricht man von Write Miss.

Es stellt sich nun die Frage, wie Cache so schnell sein kann, wenn ich doch oben geschrieben habe, das Speicher im allgemeinen eher langsam ist. Nun die Antwort ist simpel, es wird eine andere Technologie verwendet. "Normaler" Speicher oder DRAM besteht aus einem Kondensator und einem Transistor der es erlaubt die Ladung dieses Kondensators auf den Datenbus zu legen. Das Entladen und Laden dauert aber jedem Kondensator eine kurze Zeitspanne. Cache Speicher (SRAM) bestehen aus 6 (L2) bzw. 8 (L1) Transistoren, die eine Ladung in einem Flip-Flop speichern. Diese können wesentlich schneller ausgelesen und beschrieben werden als DRAM. Dafür ist der Flächenverbrauch für ein Bit viermal so groß.

Mit dem 486 wurde der Cache in den Prozessor integriert und L1 Cache genannt, ein zweiter Cache auf dem Motherboard wurde zum L2 Cache. Das Prinzip: Sind die Daten nicht im kleinen aber schnellen L1 Cache, so sind sie vielleicht im größeren und etwas langsameren L2 Cache, und erst dann muss man auf den Speicher zugreifen. Bei einem Designs wie dem K6-III oder Alpha gibt es sogar L3 Caches mit bis zu 2 MByte Größe. Auf den Prozessorbildern der unten stehenden Bilder der Pentium III / 4 und Prozessoren fallen die Caches durch die Felder mit gleichmäßiger hoher Reflexion auf. Während heutzutage alle Prozessoren Caches haben (Bei Motorola z.B. mit der MC 68030 eingeführt), sind diese bei Mikrocontrollern eher selten. Grund dafür ist der Preis - Die Caches in SRAM Technologie haben erheblich mehr Transistoren als die Prozessorkerne, so das die Ausbeute pro Waver sinkt. Darüber hinaus benötigen die CPUs so mehr Strom.

Die Verwaltung von Caches, sowie ihr schneller Zugriff ist heute essentiell für die Performance eines Prozessors. Ein Großteil der Entwicklung und Chipfläche geht heute auf die Optimierung der Caches drauf. Was der Cache ausmacht kann man leicht selbst ausprobieren. Man kann im BIOS nämlich diese ausschalten. Macht man das so ist auch der neueste Pentium 4 nicht mehr viel schneller als ein langsamer 486 er (dieser aber mit Cache).

Eine Untersuchung von ct beim Pentium 4 mit 3.06 GHz ergab, dass dieser bei den meisten Programmen intern nur auf den Speicher wartete. Im Worst Case (Daten weder im L1 noch L2 Cache und auch nicht über Burst einlesbar) dauerte es 124 ns bis die Daten heran tuckern - In dieser Zeit hätte der Prozessor 380 Instruktionen ausführen können. Der Grund liegt daran, das heutige Architekturen wie SD-RAM, DDR-RAM oder RAMBUS zwar sehr schnell die Daten übertragen wenn sie anliegen, die Zugriffsgeschwindigkeit aber sehr schlecht ist. Abhilfe könnten hier entweder RAM's mit höherer Zugriffsgeschwindigkeit bieten, wie sie z.B. für Grafikkarten eingesetzt werden, vielleicht als zusätzlicher L3 oder L4 Cache. Billiger geht es indem man mehrere Bänke bestückt und die Zugriffe auf diese verteilt. Dies wird bei größeren Servern so gemacht. Ein PC kommt aus Preisgründen meistens nur mit einem RAM Riegel und hat meistens auch nur 2-3 Steckplätze für Speicher.

Virtueller Speicher

80386 Mit dem 386 zog auch eine neue Möglichkeit in den Prozessor ein: Virtueller Speicher. Obgleich der 386 4 Gigabyte Speicher adressieren konnte spendierte ihm Intel eine MMU. Diese Memory Management Unit tat nun nichts anderes als für verschiedene Programme ihnen jeweils vorzuspielen, sie hätten den gesamten 4 Gigabyte Adressraum für sich alleine. Dabei nutzt sie dafür eine 48 Bit Adresse. Die MMU mappte diese dann im realen Speicher oder wenn dieser nicht reichte informierte der Prozessor das Betriebsystem, das er nun den Speicher von Programm × gerade braucht und dieses doch den Inhalt mal auf die Festplatte auslagern sollte. Damit dies nicht in zuviel Arbeit ausartet wurde der Speicher in kleine Scheiben von 4 Kilobyte oder 4 Megabyte aufgeteilt und jeweils die Belegung von einer 4 Kilobyte Scheibe in einer Tabelle, der TLB gespeichert.

Mit dem Pentium-Pro (P6) und den auf seiner Architektur aufbauenden Modellen Pentium II und III wurde dieses Speichermanagement verbessert indem man nun nicht nur 4 MByte und 4 KByte große Seiten ansprechen konnte sondern jede Zweierpotenz, die TLB wurde erweitert und der normale Adressraum von 4 auf 64 Gigabyte erhöht. Alle Windows Varianten bleiben aber noch immer im 4 Gigabyte Rahmen. Es macht also keinen Sinn einen Windows 2000 Server mit mehr als 4 GByte Speicher auszustatten. (Zumal das Betriebssystem die oberen 2 GByte des Speichers für sich reserviert).

Virtueller Speicher ist nichts neues, schon die berühmte VAX hatte ihren Namen 1977 nach diesem Konzept bekommen. Beim Intel 386 wird vom Prozessor z.B. ein 48 Bit breiter virtueller Speicher unterstützt. In diesem kann es sehr viele Prozesse mit max. 32 Bit Breite (4 GB) geben. Die Auslagerung übernehmen Betriebssystemroutinen die vom Prozessor über bestimmte Interrupts angestoßen werden, wir haben es hier also mit einer Hard/Softwarelösung zu tun - entsprechend hat jedes Betriebssystem eine etwas andere Lösung das Swappen zu realisieren. Allen gemeinsam ist das man auf der Festplatte einen Bereich (Datei, Partion) hat die ausgelagerte Prozesse aufnimmt. Damit kann man:

  1. Programme laufen lassen die größer als der Arbeitspeicher sind (aber kleiner als 4 GB)
  2. sehr viele Prozesse die zusammen größer als 4 GB sind laufen lassen
  3. und DOS als virtuellem PC emulieren.

Parallele Ausführung: Superskalares Design

Intel bekam mit der Weiterentwicklung des 8086 immer mehr Probleme. Anders als Intel dachte, wurden zum Beispiel die neuen Modi und die 32 Bit Register des 286 und 386 nicht in Betriebssystemen genutzt, so das bis Anfang der neunziger Jahre ein 386 oder 486 im wesentlichen als schnelle 8086 genutzt wurden. Natürlich stieg die Performance zuerst rasch an, durch die Reduktion der durchschnittlichen Ausführungsgeschwindigkeit der Befehle an. Ein 80286 war 2,4 mal schneller als 8086, doch dann wurde der Zuwachs immer geringer ein 386 noch 1,6 mal schneller als ein 286, ein 486 noch 1,5 mal schneller als der 386 und der Pentium nur noch 1,3 mal schneller. (Alle Angaben bei gleicher Taktfrequenz). Damit man ab dem 486 überhaupt noch einen Gewinn erzielen konnte ging man zu einem neuen Konzept über. Man führte beim Pentium zwei Fliesskomma und zwei Integer Einheiten ein. Idealerweise hätte man so die Performance so um das doppelte steigern können. Man nennt ein solches Design superskalar. Das Prinzip: Der Prozessor hat mehrere Funktionseinheiten die entweder durch eine gemeinsame Pipeline oder separate Pipelines aus dem L1 Cache versorgt werden. Es gibt mindestens 4 grundlegend verschiedene Funktionseinheiten:

Betrachten wir folgendes Codestück:
MOV AX,100   ; 100 in Register AX laden
MOV BX,200   ; 200 in Register BX laden
ADD AX,BX    ; AX und BX addieren, das Ergebnis steht in AX
MOV [4567],AX; Das Ergebnis in Adresse 4567 speichern
INC CX       ; CX um 1 erhöhen
DEC DX       ; DX um 1 erniedrigen

Die ersten zwei Operationen erfordern die Laden/Speichern Einheit, genauso die vierte. Die dritte und fünfte/sechste beschäftigt die Integer Einheit. Man kann zumindest die Befehle 4 und 5/6 parallel ausführen, wenn man zwei Load/Store Einheiten hat auch die Befehle eins und zwei parallel. So kann man die Geschwindigkeit vervielfachen: In einem Prozessor wie dem Itanium sitzen 17 Funktionseinheiten, die theoretisch 6 Befehle gleichzeitig ausführen können.

Idealerweise - Denn in Wirklichkeit gab es einige Hindernisse. Der Maschinencode hat sich nicht geändert, d.h. der Programmierer und Compiler kann nicht entscheiden welche Einheit er benutzen will. Er kann nur durch Befehle die nicht voneinander abhängen bewirken, das diese parallel abgearbeitet werden. Weiterhin war beim Pentium es so, das diese ALU's und FPU's nicht voneinander unabhängig waren. Die Ausführungszeit der langsameren blockierte auch die zweite. Wurde z.B. ein lang dauernder Divisionsbefehl in einer ALU ausgeführt so musste die zweite Däumchen drehen, auch wenn sie nur ein Register um eins erhöhen musste. Schon in den sechziger Jahren hat man aber eine Technik erfunden die dies umgeht: Unabhängige Einheiten die Befehle umgruppieren können (Scheduling) oder in einer anderen Reihenfolge ausführen (Out of Order Execution). Erst bei der P6 Architektur (Pentium Pro) führte dies Intel auch ein..

Prinzipiell könnte man die immer höhere Integration zu mehr Einheiten nutzen, doch schon beim Pentium 4 geht man in dieser Hinsicht einen Weg zurück. Das grundsätzliche Problem ist das alle derzeitigen Mikroprozessoren keinen Weg kennen die ALU's und FPU's nach außen hin sichtbar zu machen. Sowohl für den Compiler wie Assemblerprogrammierer gibt es nur eine Recheneinheit. Er kann nun versuchen die Befehle so anzuordnen das diese parallel ausgeführt werden können. Doch oft ist dies nicht möglich. Bei den x86 Prozessoren z.B. machen die wenigen Allzweckregister es notwendig das man diese gemeinsam für verschiedene Daten nutzt. Zudem kann ein Compiler nie wissen ob der Code auf einem Pentium 4 (eine FPU), einem Pentium II/III (zwei FPU's) oder einem Athlon (drei FPU's) läuft. So ist der Pentium 4 bei Code der zwei FPU's voraussetzte sogar langsamer als ein Pentium 3 mit geringerer Taktfrequenz.

Die Lösung dafür wird seit langem diskutiert. Am sinnvollsten scheint es wie früher bei den Großrechnern jeder Recheneinheit einen eigenen Registersatz zuzuweisen und nach außen hin ansprechbar zu gestalten. Noch radikalere Konzepte teilen den Recheneinheiten Tasks zu - Prozesse die im Betriebssystem verankert sind. Derartige Tasks sind nur für eine Millisekunde aktiv, aber gegenüber den kurzen Codesequenzen die sonst vorkommen sind das richtige Ewigkeiten. So fallen Switches zwischen den Tasks kaum ins Gewicht. Der Vorteil wäre, das ein Rechner für den Benutzer auch unter großer Hintergrundlast immer gleich schnell wäre und Programme mit viel Rechenleistungsbedarf einfach mehrere Tasks starten, so wie z.B. ein Spiel für den Aufbau des Hintergrundes, die Steuerung von Figuren und den Aufbau des Vordergrundes. Da jeder Task unabhängig ist kann man so bei einem Prozessor mit n Recheneinheiten die n fache Performance erreichen. Dies wird z.B. der Alpha 21364 einsetzen. Intel hat beim Itanium einen anderen Weg eingeschlagen und die Befehle in Bündel von 3 gruppiert und ihnen eine Information über Abhängigkeiten eingeprägt.

Pipelines

Pentium III Eine Befehlsausführung besteht normalerweise aus mehreren Schritten: Daten aus dem Speicher holen, dekodieren, evt. Operanden aus dem Speicher holen, Ausführen, Ergebnisse Zurückschreiben etc. Selbst einfache Befehle benötigen so mehrere Takte zur Ausführung. Komplexe Befehle wie die Division benötigten beim 8086 bis zu 171 Takte. Sie erinnern sich noch an den Maschinenzyklus?

Um die Geschwindigkeit der Befehlsausführung zu steigern wurden in jeder Intel das Konzept der Pipeline vervollkommnet. Eine Pipeline holt bei jedem Takt ein Byte oder mehrere aus dem Speicher. Dann beginnt bei jedem Takt ein weiterer Schritt der Ausführung eines Befehls. Benötigt ein Befehl 5 Takte zur Ausführung so kann man mit einer fünfstufigen Pipeline pro Takt einen Befehl ausführen. Man kann also die Geschwindigkeit der Ausführung steigern - allerdings nur solange wie linear abgearbeitet wird. Verzweigt ein Programm so sind alle Befehle in der Pipeline ungültig und es dauert lange bis diese wieder gefüllt ist und wieder schnell arbeitet. Man nennt dies auch einen "Pipeline Stall". Dies wurde beim neuen Design des Pentium-Pro verhängnisvoll. Er bekam einen Pipeline Stall wenn man in ein 16 Bit Register schrieb und kurz darauf einen 8 Bit Wert aus einer Hälfte des Registers auslas. Intel ging beim Design davon aus, das die Ankündigung von Microsoft stimmte, das neue Windows 95 wäre ein 32 Bit Betriebsystem und maß diesen in Windows 3.1 oft verwendeten Befehlsfolgen keine Bedeutung zu. Die Folge: Da Windows 95 noch voller 16 Bit Treiber war ein Pentium-Pro 166 plötzlich nur noch so schnell wie ein Pentium 120 war.

Sprungvorhersage

Intel hat bei den Designs die Pipeline immer mehr verlängert: Von 5 Stufen beim 486 über 13 stufen beim Pentium II/III (Bild links) zu 20 Stufen beim Pentium 4. Das Problem der Pipeline Stalls wird so natürlich problematischer. Daher führte Intel ab dem P6 einen Mechanismus ein, der zuerst unter Branch Execution Table und bei dem P4 als Trace Execution Cache firmiert. Der Prozessor schaut bei den folgenden Adressen nach ob diese Sprünge enthalten und versucht die Wahrscheinlichkeit das dies der Fall ist "vorauszuahnen" und merkt sich dann die folgenden Daten und holt sie aus dem Speicher. Man nennt dies auch spekulative Ausführung. Aus dem 512 Byte Zwischenspeicher beim Pentium 3 wurde beim Pentium schon ein 4 KByte Speicher - die Vergrößerung um das achfache soll die Hit-rate um 30 % steigern. Ein Vorteil von langen Pipelines ist das pro Stufe weniger zu tun ist - man braucht also pro Stufe weniger Zeit und kann so die Taktfrequenz steigern. Dies tat man auch beim Pentium 4 der 2001/2002 die Taktfrequenz verdoppelt hat. Der Athlon konnte ohne diese Technologie seinen Takt in der gleichen Zeit langsamer steigern.

Beim Pentium Pro wurden die Pipelines der einzelnen Einheiten auch voneinander entkoppelt, allerdings wird dies Intel beim ersten 64 Bitter "Itanium" wieder zurücknehmen. Bei der langen Pipeline des Pentium 4 verwundert es nicht, das er eine 8 mal größere Tabelle für Sprungvorhersagungen hat - Ein Pipeline Stall verlangsamt den Prozessor um so mehr, je länger die Pipeline ist.

Systemerweiterungen

Seit dem 8086 hatten alle Prozessoren immer die gleiche Anzahl an Registern. Diese wurden zwar mit dem 386 er auf 32 Bit verbreitert, doch die Anzahl blieb. Dagegen wiesen neue Prozessoren wie Alpha 32 oder gar 64 Register auf. Mit der MMX Version des Pentium gab es eine erste Erweiterung, jedoch mehr eine Marketing Maßnahme als eine sinnvolle Erweiterung. Bei der MMX Erweiterung können die Fliesskommaeinheiten anstatt Fliesskommarechnungen auch mehrere einfache Integer Berechnungen mit 8 oder 16 Bit parallel durchführen. Praktisch nutzbar war dies in den seltensten Fällen. Mit dem Pentium II wurde dies zum leistungsfähigeren SSE Einheit erweitert die nun nicht die Fliesskommaregister benutzt sondern eigene 64 Bit Register, mit dem Pentium 4 werden diese auf 128 Bit erweitert.

Dies bringt einen Performancegewinn bei allen Operationen bei denen mehrere Werte simultan denselben Rechnungen unterzogen werden wie z.B. JPEG Codierung / Dekodierung. Bei der normalen "Wald und Wiesen Applikation" jedoch eher nicht. Es lohnt sich daher diese beiden Architekturen die man auch auf anderen Prozessoren findet genauer zu betrachten.

SIMD

Kern von MMX, SSE oder 3D-NOW, aber auch ähnlichen Erweiterungen wie Altivec bei Motorola ist eine Architektur die man als SIMD bezeichnet. SIMD steht für Single Instruction Multiple Data. Es sollen also mit einer Instruktion mehrere Daten zugleich bearbeitet werden. Auf der Intel Seite fing dies als MMX an: Es wurden die max. 80 Bits langen Fliesskommaregister als Speicher für

benutzt und mit einer Operation genau 8,4 oder 2 Werte gleichzeitig bearbeitet. MMX ist also auf Ganzzahlen von 8-32 Bits beschränkt. Zudem musste man bei MMX immer zwischen MMX und Fliesskommaberechnungen umschalten, da beide dieselben Register benutzen. Der Vorteil ist nur, das man hier prinzipiell etwa doppelt so breite Register wie im Prozessor hat.

AMD's 3D-NOW erweiterte dieses Konzept im wesentlichen darauf das man nun auch 2 Fliesskommazahlen mit einfacher Genauigkeit (32 Bits) benutzen konnte, das ist für manche Spiele ganz interessant, für die meisten Zwecke ist jedoch eine erheblich höhere Genauigkeit nötig. (Eine 32 Bit Fließkommazahl hat nur eine Genauigkeit von 7 Stellen, beim Rechnen mit Millionen Beträgen gibt es daher schon Rundungsfehler im Pfennig Bereich, aber wer Millionen hat kann sich sicher auch einen schnelleren Rechner leisten...)

Bei SSE, hat man das erkannt nun endlich Nägel mit Köpfen gemacht:

Damit kann man wenn dies gezielt einsetzt die Performance besonders beim Bearbeiten von Daten die immer denselben Operationen unterworfen werden enorm steigern.

VLIW

Eine Architektur die man bei Intels Itanium Prozessor findet, aber auch bei zahlreichen DSP Prozessoren ist VLIW. (DSP Prozessoren sind Digitale Signal Prozessoren. Ihre Stärke ist das schnelle Verarbeiten immer gleicher Daten wie Entzerren, Entrauschen, Grundschwingungen ermitteln. DSP Prozessoren findet man in Unterhaltungselektronik (CD-Player, DVD, Automobilen (Motorüberwachung) oder auf anspruchsvollen Soundkarten). Wie schon erwähnt haben heute viele Prozessoren mehrere Rechenwerke auf dem Chip. Bei der Intels 32 Architektur muss der Prozessor mühsam versuchen, diese mit den Daten zu versorgen, dazu Befehle umgruppieren, Sprünge vorausberechnen etc. Bei VLIW verlagert man diese Arbeit praktisch auf den Compiler.

VLIW steht für Very Long Instruction Word und ist wohl bei der Itanium Architektur am besten erklärt. Hier besteht ein Befehl eigentlich aus 3 Befehlen die zusammen ein 128 Bit "Packet" bilden. Jeder Befehl ist 41 Bits breit und in weiteren 5 Bits steht drin welche Daten (Integer, Fliesskomma, Daten) es sind und wie sie voneinander abhängen. Der Gedanke ist so: Der Prozessor holt sich ein 128 Bit Packet. Danach kann er anhand der 5 Statusbits sofort jeden Befehl an die richtige Ausführungseinheit weiterleiten und diese parallel ausführen. Die gesamte Logik die bisher bei der I32 Architektur diese Verteilung der Befehle gemacht hat kann entfallen. Bei DSP Prozessoren die normalerweise nicht so hoch integriert sind funktioniert dieses Konzept sehr gut, die TMS 32064 Serie erreicht so max. 8 Instruktionen/Takt, während ein Pentium 3 nur zirka 3 Instruktionen pro Takt als Maximum erreicht. Bei Intels Itanium ist der große Geschwindigkeitsgewinn durch VLIW bislang ausgeblieben. Der Nachteil von VLIW ist: Wenn es nicht möglich ist die Befehle parallel auszuführen (z.B. wenn es mehrere Fliesskommabefehle sind die voneinander abhängen), dann muss der entsprechende Codeteil leer bleiben. VLIW Code ist also immer umfangreicher als normaler Code.

SIMD und VLIW sind praktisch nur nutzbar, wenn ihr Compiler dies leistet. Meine Experimente zum Thema Benchmark ergaben hier bei C Compilern, dass diese in der P6 Einstellung nur Befehle umstellen, jedoch keinerlei MMX, 3D-NOW oder gar SSE Befehle verwenden. Dazu müsste man auf Compiler von Intel mit trickreichen Optimierungen ausweichen. Solange aber das Gros der Entwickler mit Visual Studio, CBuilder oder Watcom arbeitet muss man sich nicht wundern wenn man MMX und SSE in keiner Applikation findet.

Beide Konzepte ergeben zumeist die höchste Performancesteigerung bei so genannten "Streaming" Operationen: Wenn ein Datenstrom einer Reihe von Operationen unterworfen wird, die relativ einfach sind. Das sind heute Dinge wie Kompression/Dekompression, Codierung/Decodierung oder allgemein die Bearbeitung von Grafik. Daher etablierten sich beide Konzepte zuerst in Signalverarbeitungsprozessoren die Spezialisten auf diesem Gebiet sind. Eine normale Windows Wald-und-Wiesen Applikation wird durch beide Konzepte kaum schneller, da man hier sehr viele Codeteile durchläuft, die schwerer optimierbar sind, als die kleinen Routinen von Decodern.

Register Renaming

Intels Antwort auf RISC war seit dem Pentium-Pro eine Erweiterung des Registersatzes. Allerdings kann der Programmierer diese neuen Register nicht nutzen. Der Prozessor der nun den x86 Code in einfacheren Code umsetzt benutzt diese intern und legt Zugriffe auf die Register um. Wozu? Nun der 8086 hat für den Programmierer 8 freie Register: Die Allzweckregister AX,BX,CX und DX und dazu noch 4 Segmentregister. Das ist so wenig dass man oft Werte auslagern muss. Ein Programmierer ist z.B. gezwungen erst einen Wert in AX zu berechnen, dann das Ergebnis abzuspeichern und dann AX mit einem neuen Wert zu füllen und eine weitere Berechnung zu machen. In diesem Fall nützt Register Renaming, indem man nicht waren muss bis der Wert aus AX gespeichert ist (das dauert) sondern ein anderes Register das gerade frei ist zu AX deklarieren kann und dort die Operationen durchführen kann.

Der Pentium 4 hat so 128 interne Register also 16 mal mehr als der Programmierer direkt sehen kann. Beim Sledgehammer - dem ersten 64 Bit Prozessor von AMD geht man einen anderen Weg und verdoppelt im 64 Bit Modus die für den Programmierer nutzbaren Register auf je 16 Fliesskomma und Integer Register. Da ein Compiler meistens durch den Quellcode etwas schlauer ist, welche Variablen man häufig braucht und welche nicht ist es immer geschickter wenn der Prozessor direkt mehr Register zur Verfügung stellt. Bei einer alten Architektur wie der von Intel ist dies schwer möglich da man ja in den Opcodes mehr Bits braucht um die größere Anzahl von Bits zu codieren.

Das Register Renaming hat aber auch andere Vorteile, wenn es darum geht die CPU unabhängiger vom Speicher zu machen. Der Grundgedanke ist mehr Register auf dem Chip zu haben als man als Programmierer anzusprechen und zwischen diesen umzuschalten. Es gibt hier verschiedene Konzepte. Verwirklicht ist schon das Windows Konzept: Wenn ein Prozessor ein Unterprogramm ausführt, dann benötigt dieses einen Teil der Register um Daten zu verarbeiten. Bei herkömmlichen Architekturen "rettet" man diese Register auf den Stack - Einen Hauptspeicherbereich der mittels eines speziellen Registers adressiert wird und von dem man nur die letzten Daten holen kann und restauriert diese nach der Ausführung des Unterprogramms wieder. Auch wenn die Befehle durch die Adressierung über einen Zeiger der vom Prozessor verwaltet wird keine Speicheradresse benötigen fallen doch Zugriffe auf den Hauptspeicher an, der langsam ist.

Das Windows Konzept, z.B. verwirklicht in der SPARC CPU teilt dagegen die Register in globale - immer ansprechbar - und lokale ein. Die lokalen Register werden bei einem Unterprogrammaufruf einfach durch andere ersetzt, deren Inhalt bleibt erhalten und wird nach der Ausführung durch Setzen eines Zeigers auf die ursprünglichen Register wiederhergestellt. Bei einer schon erhältlichen CPU ist so ein Fenster 16 Register breit aus einem Satz von 128 Registern, d.h. es ist maximal eine Schachtelungstiefe von 128 / 16 = 8 möglich. Dann muss auch diese CPU Daten auslagern.

In gewisser Weise ist das Registerrenaming eine Art Register-Cache auf der CPU, jedoch erheblich transparenter als die Verwaltung des Caches. Es ist damit zu rechnen, das man dies noch extensiver nutzen wird.

Der 386 er Emulator

Pentium 4 Mit dem Pentium hat Intel den Prozessorkern auf eine RISC Einheit umgestellt. Seitdem zerlegt der Prozessor seine ankommenden Befehle in einfachere RISC Operationen und mappt die vierzehn 80x86 Register auf 32 interne RISC Register um. Dies machen auch die Konkurrenten Cyrix und AMD, weshalb die Prozessoren nicht mehr mit den Taktfrequenzen vergleichbar sind, da jeder RISC Kern bestimmte Befehle besser ausführt als ein Konkurrenzprozessor, der dafür andere Stärken hat. Beim Pentium 4 werden anders als beim Pentium II/III die fertig übersetzten Befehle im L1 Cache gesammelt, diese haben eine Breite von 118 Bits, also erheblich mehr als die meisten 8086 Befehle.

So ist ein Pentium II/III heute nichts anderes als ein komplexer Emulator, der so tut als wäre er ein 386 er. Erstaunlich ist das es Intel damit zwar nicht gelingt den schnellsten Prozessor zu bauen, aber doch in der Oberliga mitzuspielen. Doch einen Preis muss Intel aufbringen: Es gelingt nur mit einem sehr komplexen Chip (Intels Pentium 4 (Bild links) hat 42 Millionen Transistoren, der schnellere Alpha 21264 dagegen nur 15) und hohen Taktfrequenzen (1.4 MHz für die gleiche Performance die der Alpha bei 700 MHz erreicht). Wenn man allerdings durch enorme Stückzahlen die Serienkosten senken kann und die Entwicklungskosten umlegen kann, spielt dies keine Rolle. Dagegen musste die Konkurrenz bis auf AMD die Segel streichen.

Ein Pentium 4 hat dieses Spiel auf die Spitze getrieben. Intern ist ein Pentium 4 ein RISC Prozessor mit 7 Einheiten - anstatt einer ALU und einer Bus Interface Unit beim 80x86. Er kann z.B. 4 ALU's gleichzeitig einsetzen. Intern verfügt der Prozessor auch über 128 Register die er auf die nach außen sichtbaren 8 User Register spiegelt (Register Remapping). Nach dem Dekodieren der 80x86 Befehle landen diese im L1 Cache der nur RISC Operationen speichert. Je nach Befehl 1-4 im Regelfall (2 im Durchschnitt).

Doch was hat der Benutzer, der Programmierer davon? Er sieht 14 Register, nicht 128. Er sieht eine ALU nicht 4 und muss durch trickreiche Umstellungen des Codes dafür sorgen das diese mit voller Geschwindigkeit arbeiten. Daher spricht Intel auch immer vom optimierten Code. Das Dumme ist nur es gibt nicht den optimierten Code. Ein optimierter Code für den Athlon ist ein anderer als der für den Pentium III und wieder ein anderer für den Pentium 4. So ist der Pentium 4 bei 1.4 GHz langsamer bei SSE Befehlen als ein Pentium III - dieser hat zwei SSE, der P4 nur eine, weshalb Code der abwechselnd zwei SSE ansprechen will langsamer ist. Dagegen ist mit Erweiterung dieses Designs beim Pentium Pro das Programmieren in Assembler schwieriger geworden: Es ist seitdem nicht mehr möglich die Ausführungszeit in Takten präzise anzugeben: Sie hängt davon nun ab ob der Befehl unabhängig von anderen ausgeführt werden kann, ob es keine Probleme in der Pipeline gibt etc. Es gibt nur noch Spannbreiten für die Ausführungszeiten. Dies ist auch der Grund warum Prozessoren innerhalb der x86 Reihe nur schwer vergleichbar sind. Ein Athlon mit 1400 MHz hat also nicht die gleiche Geschwindigkeit wie ein Pentium III oder 4 bei derselben Taktfrequenz. Daher findet man öfters ein so genanntes "Rating", also eine Vergleichsangabe wie z.B. bei den Athlons XP.

Neubeginn bei 64 Bit

Itanium 2001 kommt auch bei Intel der Einstieg in die 64 Bit Generation die andere Firmen wie Compaq oder MIPS schon vor Jahren vollzogen haben. Man kann spekulieren ob es des bleibende Erfolg der 32 Bit x86 Architektur ist oder die nur zaghaften Bestrebungen von MS ihr 32 Bit Betriebssystem Windows NT auf 64 Bit zu erweitern welche die Entwicklung so lange hinausgezögert haben. Aber Intel ist zum ersten mal gewillt einen Schnitt zu machen. Der neue Prozessor hat einen Kompabilitätsmodus. In dem bisheriger x86 Code weiter funktioniert - allerdings nur so langsam wie ein Pentium II mit 300 MHz. Neu ist ein neuer 64 Modus mit einer neuen Architektur: RISC Kern mit konstanten 41 Bit Befehlslängen, 128 Registern. Um beides realisieren zu können hat man Abstriche bei den vielen Features gemacht. Die 4 ALU's und 2 FPU haben z.B. keine Möglichkeiten mehr Abhängigkeiten zu erkennen und Befehle umzugruppieren - dies hat Intel auf den Compiler ausgelagert, siehe Abschnitt über VLIW. Anders hätte man den 64 Bit Prozessor samt 32 Bit x86 Kern nicht in 25 Millionen Transistoren fertigen können - zum Vergleich der aktuelle Pentium 4 hat 42 Millionen. Mehr dazu in einem eigenen Aufsatz.

Doch noch vor Erscheinen hat der 64 Bit "Itanium" Chip schon Konkurrenz bekommen: AMD's neuer 64 Bit Prozessor "Sledgehammer" ist weitgehend x86 Kompatibel. Einige Opcodes mussten im 64 Bit Modus umdefiniert werden, aber der Programmierer hat im Prinzip denselben Befehlssatz wie beim x86 vor sich. Auch die Register wurden nur um je 8 Fliesskomma und Integer erweitert. Dafür benötigt die 64 Bit Erweiterung nur 5 % zusätzliche Chipfläche. Es wird spannend zu sehen welches Konzept sich durchsetzten wird.

Zukünftige Neuentwicklungen

Um die Geschwindigkeit zu steigern gibt es verschiedene Möglichkeiten. Im Intel Lager hat man das Problem, das die parallelen Einheiten nur wenig genutzt werden. Hier ist es das Ziel das der Code die Einheiten besser ausnutzt. Beim Itanium z.B. legt der Compiler der ja den Sourcecode kennt fest wie Befehle voneinander abhängig sind. Funktioniert dies so vereinfacht dies die Logik des Prozessors und erhöht die Geschwindigkeit.

Ein anderer Weg ist ganz einfach von vornherein unabhängige Prozesse zu nehmen - und die gibt es schon heute genug. Jedes Betriebssystem hat selbst wenn gar nichts passiert einige Dutzend von einander unabhängigen Threads also unabhängigen Programmen, und wenn ein Prozessor für jeden Thread eigene Register hat so können diese parallel ausgeführt werden. Diesen Ansatz verfolgte z.B. Compaq bei der Prozessorentwicklung. Entscheidend ist, das man Threads die nichts zu tun hat schnell durch andere ersetzen kann die Rechenzeit benötigen, d.h. das vor allem das Wechseln der Register schnell geht. Platz genug für viele Register ist heute schon vorhanden - schlussendlich kommen heute Prozessoren schon mit 96 KByte L1 und 256 KByte L2 Cache on Chip.

IBM will die Geschwindigkeit durch mehr Bandbreite und unabhängige Einheiten erbringen. Eine neue Architektur soll auf einem Chip bis zu 16 Prozessoren beinhalten, die über einen schnellen Bus verbunden sind und einen gemeinsamen Speicher adressieren. Dies geht nur mit breiten Datenpfaden, wenn man die Geschwindigkeit intern nicht enorm hoch treiben will. Dieser Ansatz ist so neu nicht. Bei Großcomputern setzte man schon früh auf Busse von bis zu 256 Bit um so mehr Daten auf einmal zu verarbeiten. Betrachtet man die Interna des P4, wo der Addierer 4.5 GOps schaffen soll, aber durch die Datenpfade nur max. 3.6 GOps transportiert werden so scheint dieser Ansatz nicht so dumm zu sein. Vor allem macht er wenig Architekturveränderungen bei höherer Integrationsdichte nötig - man bringt einfach mehr Prozessoren auf dem Chip unter.

Alle Konzepte setzen mehr oder weniger auf RISC: Es ist schon schwierig genug dem Code trickreich auf mehrere Prozessoren umzulegen. Wenn man nun auch komplexe Befehle hat wird es sehr schwierig. Auch unterstützen die Prozessoren mehr und mehr Hochsprachen indem z.B. Register eingeblendet werden können - für eine Unterprozedur die ihre eigenen Werte hat. Fast alle Designs gehen auf mehr Register oder längere Breiten die dann für SIMD Operationen wie MMX oder SSE genutzt werden. Auch die Verlagerung der Intelligenz vom Prozessor auf das Betriebssystem - Bearbeiten von einzelnen Tasks pro Funktionseinheit beim Alpha 21364 oder auf den Compiler - Die EPIC Architektur die im Code Abhängigkeiten der Befehle speichert zeigt eine Tendenz zu einem einfacheren, linearen Design.

Vieles ist eigentlich nichts neues, sondern vor Jahren schon in Jahrzehnten in Großrechnern eingeführt. Auch das Arbeiten von mehreren Prozessoren zusammen gab es schon Mitte der achtziger Jahre bei den Transputer Chips von Inmos. Ideal wäre es wenn man im Quellcode die einzelnen Einheiten ansprechen könnten. Doch wäre damit nicht viel gewonnen - In 23 Jahren Intel Entwicklung stieg die Zahl der Einheiten pro Prozessor von 2 auf 17. Ein neuer Prozessor hätte auch Nachfolger mit noch mehr Einheiten die man dann wiederum nicht direkt über den Quellcode ansprechen könnte.

Das Energieproblem

Bisher lagen bei allen Prozessorherstellern das Hauptaugenmerk auf der Geschwindigkeit. Das führte dazu, das die Rechner immer mehr Energie verheizten. Die Kühlkörper werden immer größer und das Wärmeproblem immer stärker. Ein IBM-PC hatte ein 75 Watt Netzteil, ein Athlon PC braucht heute ein 300 Watt Netzteil und ein vierfach Itanium System 2.4 KW. Die Zukunft wird sowohl von konstruktiver Hinsicht (man kann einen PC nicht flüssig kühlen wie Großrechner) wie auch ökologischen Gesichtspunkten einem Prozessor gehören der wenig Strom verbraucht. Ein Beispiel ist z.B. Transmetas Crusoe, aber auch zahlreiche "Nicht x86" Prozessoren haben MIPS/Watt Leistungen die einen Pentium 4 oder Athlon als wahren Energieverschwender dastehen lassen. Dieser Punkt wird auch aus anderer Hinsicht für die Prozessorhersteller interessant. Im Jahre 2001 gab es einen rapiden Einbruch bei dem Computermarkt. Nach 25 Jahren expansiven Wachstums ist der Markt weitgehend gesättigt. Fast jeder in den Industriestaaten hat einen Computer oder Zugang zu einem. Es gilt nun neue Märkte zu erobern z.B. indem man mehr PDA's, Set-Top Boxen, oder Videorekorder mit Festplatte verkauft. Der gesamte Bereich der Unterhaltungselektronik steht noch als Markt zur Verfügung um einen PC auch denen zu verkaufen denen er bisher zu laut, umständlich zu bedienen oder zu unansehnlich war. Damit allerdings der PC neben der Stereoanlage im Wohnzimmer stehen kann muss er vor allem leise werden - dazu müssen die Lüfter raus und damit der Energieverbrauch rapide gesenkt werden. Desgleichen gilt bei tragbaren Geräten. Bei PDA's findet man keine Intel Prozessoren - sie verbrauchen einfach zuviel Strom.

Als Intel mit den hochgetakteten Versionen des Pentium 4 eine thermische Verlustleistung von 125 Watt erreichte war allerdings auch das Problem

Mikrocontroller

Der Z80 Prozessor gibt es auch als System on a ChipWenn bisher vor allem von Prozessoren und auch hier vor allem von der Intel Serie die Rede war, so vor allem um die Entwicklung über 30 Jahre aufzuzeigen. Darüber hinaus sind diese Prozessoren auch jedem Anwender bekannt. Doch kein Artikel über Rechnerarchitekturen kommt ohne die Beschreibung von Mikrocontrollern und DSPs aus.

Der Mikroprozessor wird im amerikanischen Sprachgebrauch oft als CPU (Central Processing Unit = Zentrale Verarbeitungseinheit) abkürzt, was seine Funktion besser beschreibt als das Wort Prozessor. Er ist die Rechenzentrale ihres PCs, doch er ist nicht alleine und kann auch nicht alleine arbeiten. Sie brauchen mindestens noch ein bisschen ROM (um zumindest den Rechner starten zu können und von außen vielleicht ein größeres Programm laden zu können), und auch noch RAM für Daten. Darüber hinaus muss der Prozessor mit der Außenwelt kommunizieren. Er hat dazu einen Steuerbus. Der alleine nützt ihm allerdings nichts, denn die Peripherie hat meistens andere Anschlüsse und verlangt ein Protokoll. Bei der Seriellen Schnittstelle zum Beispiel ein Handshake, das Quittieren jedes Signals. Dies kann der Mikroprozessor erledigen. Außer bei kleinen System machen dies jedoch spezialisierte I/O Bausteine die es fertig konfektioniert für parallele und serielle Schnittstellen gibt. Die originale IBM PC Tastatur hatte sogar einen eigenen Prozessor zur Verarbeitung der Daten.

Diese Chips machen auch die Hauptmasse der Kosten eines Mainboards aus, wobei dies heute durch wenige Bausteine noch relativ preiswert ist. In den achtziger Jahren als es noch Dutzende von Bausteinen waren, lag der Preis eines Mainboards noch in der Größenordnung von 1000 DM.

Für zahlreiche Anwendungen wo der Prozessor nur steuern soll und kein PC mit flexibler Ausbaufähigkeit verlangt wird, ist dies zu aufwendig und zu teuer. Daher kam man bald auf die Idee die wesentlichen Peripheriebausteine auf dem Prozessor mit zu integrieren. Einen solchen Prozessor bezeichnet man dann als Mikrocontroller. Er enthält typischerweise einige programmierbare Ausgangsports die den I/O Bausteinen entsprechen und an die man Peripherie oder Messwertwandler anhängen kann. Dazu kommen einige programmierbare Timer, dies sind Zeitgeber die nach Ablauf einer bestimmten Frist den Prozessor veranlassen ein Programm durchzuführen, z.B. regelmäßig die Herzfrequenz in einem mobilen EKG Gerät aufzunehmen. Mit integriert sind zumeist auch vom Anwender programmierbare ROMs und ein RAM auf dem Chip, Ein solcher Mikrocontroller ist somit anders als ein Prozessor autark.

Man findet Mikrocontroller häufiger als man denkt. Ein Großteil der Prozessoren die ein einem heutigen Haushalt ihre Arbeit verrichten sind solche Mikrocontroller. In einem amerikanischen Haushalt sollen es über 100 sein, davon alleine 40-50 im Auto. Mikrocontroller steuern und überwachen. Von einfachsten Aufgaben wie die Steuerung einer Mikrowelle oder Waschmaschine über Telekommunikation (Handys) bis hin zu schnell reagierenden Echtzeitsystemen (Motorsteuerung, Airbag, Herzschrittmacher).

Die fortgeschrittene Form eines Mikrocontrollers ist das System on a Chip oder Embedded System. Man versteht dabei auch das Integrieren weiterer Komponenten, im Extremfall kann man einen 486 PC mit RAM, VGA Grafik und Windows im Flash RAM auf einem Chip unterbringen. Der früher in Heimcomputer eingesetzte Z80 Prozessor (Bild rechts) ist heute als integrierter Baustein der als Webserver fungieren kann erhältlich. Er bietet 15 Internetprotokolle, Ethernetanschluss und ist Javafähig. Solche Systeme sind es die den internetfähigen Kühlschrank ermöglichen werden. PCs sind dazu viel zu teuer (außer sie bekommen einen PC für 11 Dollar, soviel kostet ein eZ80 Webserver).

Die nahe liegende Idee einen Prozessor zum Mikrocontroller umzubauen hat sich nicht durchgesetzt. Vor allem ist hinderlich das der Befehlssatz nach wie vor die integrierten Bausteine als externe Quellen anspricht. Man findet Mikrocontroller auf Basis der 80186 und Power PC Chips nur dort wo die Entwicklung auf der PC Plattform eine Rolle spielt (80x86 Serie) oder hohe Rechenleistungen gefragt sind (Power PC). Erfolgreich waren spezielle Eigenentwicklungen als Mikrocontroller wie die 8051 Serie von Intel oder die ursprünglich aus der erfolglosen MC 6800 Serie entstandenen MC68HC Prozessoren von Motorola. Auch andere PC Prozessoren wie die ARM Chips wurden als Mikrocontroller weiterentwickelt.

DSP

DSP Chips (DSP: Digitale Signalprozessoren - deswegen ist die Bezeichnung DSP Prozessoren Unsinn) sind die dritte wichtige Architekturlinie die es heute gibt. Ein Mikroprozessor spiegelt in seiner Hardware die Anforderungen von kommerziellen und technischen Programmen wieder - Er ist ein Universaltalent und verarbeitet mit seinen Befehlen vorzugsweise kleine Dateneinheiten wie Zeichen (8 Bit) oder Ganzzahlen (16-64 Bit) oder Fliesskommazahlen (32-80 Bit). Dabei werden verschiedene Werte unterschiedlich bearbeitet. Ganz andere Anforderungen liegen bei der Verarbeitung von Signalen vor. Es handelt sich dabei um gleichartige große Datenmengen wie Digitaldaten die von einer CD gelesen werden, Decodierung von MPEG Datenströmen oder die Analyse von Daten des Motors eines Automobils. Allen gemeinsam ist, das es sehr viele Daten sind, sie in Echtzeit verarbeitet werden müssen und meistens auf dieselbe Art und Weise. Im Jahre 2003 gibt es den "MiMagic 6 Mikrocontroller", der gleichzeitig bis zu 512 Datenworte bearbeitet. Bei MPEG Dekodierung bestehen Blöcke die nach demselben Prinzip verarbeitet werden aus 64 bzw. 256 Elementen in 3 Kanälen. Ein solcher Prozessor kann also einen ganzen Block auf einmal kodieren / dekodieren.

Deswegen wurden die oben angeführten Techniken VLIW und SIMD bei Digitalprozessoren zuerst eingesetzt. Diese Architekturen erlauben es mehrere Daten auf einmal zu bearbeiten. Digitale Signalprozessoren findet man heute sehr häufig in Geräten der Unterhaltungselektronik. Vom Handy über den CD Spiele bis zum DVD Spieler. Daneben auch wo Daten zeitkritisch ausgewertet werden müssen: In Motorsteuerungen und Herzüberwachungsnotfallhandys. Welche Leistung Signalprozessoren haben kann jeder nachprüfen. Zum Zeitpunkt dieses Artikels kostet ein Stand-Alone DVD Player mit Signalprozessor zum Decodieren der Signale 140 Euro. Bei einem PC muss schon ein Prozessor der 500 MHz Klasse arbeiten damit er DVDs ohne Hardwareunterstützung dekodieren kann und er kostet deutlich mehr als 140 Euro.

Zudem sehen PC Prozessoren bei typischen DSP Anwendungen sehr schlecht aus. Im Telemark Benchmark, einem Telekommunikationsbenchmark kommt die Embedded Variante des Power PC Prozessors, der MPC7447 auf einen Wert von 163.9 bei 1.3 GHz Takt. Der MIPS Prozessor Fastmath dagegen bei 2 GHz auf einen Wert von 868.3 - mehr als 5 fache! Das brachte eine Forschergruppe auf die Idee 70 Playstation 2 zusammen zu schalten - den der Grafikprozessor darin hat eine Spitzenleistung von 6.2 GFLOP. Bei speziellen Anwendungen ist dies dann ein 400 GFLOP schneller Rechner, der nur 50.000 USD gekostet hat. Für die gleiche Rechenleistung brauchte man 180 Pentium 4 Rechner mit je 3 GHz, die jedoch erheblich teurer wären.

Bedeutung von Mikrocontrollern und DSP

Sicherlich ist die Entwicklung der PC Prozessoren interessant und das Filetstück der Halbleiterindustrie. Man vergisst gerne MC und DSPs. Dies ist jedoch falsch. Natürlich macht der PC und Workstation Markt mit 23 Mrd. USD den größten Teil des Halbleitermarktes von 40 Mrd. USD im Jahre 2002 aus (MC 10 Mrd. USD, DSP 4 Mrd. USD). Sieht man sich aber die Stückzahlen an so sieht es völlig anders aus. Mikrocontroller kosten typischerweise einige € pro Chip, mehr als die Hälfte der Gesamtstückzahl sind noch 8 Bit Chips. So ist der Gesamtanteil von Intel an der Stückzahl der verkauften Prozessoren nur 2 %, selbst im 32 Bit Segment nur 20 %. Dagegen haben 2 Fertigungslinien der 68HC Serie inzwischen die 4 Mrd. Stückzahlgrenze überschritten. Wer also beruflich Assembler programmieren muss, der kommt eher mit einem Mikrocontroller in Berührung als mit einem PC Prozessor. Dazu passend haben die beiden früheren Marktführer für 80x86 Assembler Borland und Microsoft ihre Produkte seit dem Pentium nicht weiterentwickelt. Der TASM und MASM verstehen nicht einem MMX Opcodes geschweige denn 3D-NOW oder ISSE.

Fazit

Wenn in diesem Artikel andere Prozessoren nur am Rande erwähnt werden, so nicht weil sie unbedeutend sind oder Intel die Krone in der Prozessortechnik hat. Im Gegenteil! Andere Firmen mit weniger Marktanteil konnten schon in den späten Achtziger oder Anfang der neunziger Jahren reine RISC Systeme entwickeln. Motorola - Intels größter Konkurrent zu 16 Bit Zeiten hat schon 1993 den Power PC Prozessor entwickelt und die 68K Linie auslaufen lassen. MIPS und Digital (heute Compaq) konnten ohne Kompabilitätsrücksicht reine RISC Prozessoren entwickeln. Doch gerade weil Intel mit allen Tricks die Systemleistung ihrer 20 Jahre alten Architektur noch steigern konnte sind sie ein gutes Beispiel für die Technologien in modernen Prozessoren.

Zum Thema Computer ist auch von mir ein Buch erschienen. "Computergeschichte(n)" beinhaltet, das was der Titel aussagt: einzelne Episoden aus der Frühzeit des PC. Es sind Episoden aus den Lebensläufen von Ed Roberts, Bill Gates, Steve Jobs, Stephen Wozniak, Gary Kildall, Adam Osborne, Jack Tramiel und Chuck Peddle und wie sie den PC schufen.

Das Buch wird abgerundet durch eine kurze Erklärung der Computertechnik vor dem PC, sowie einer Zusammenfassung was danach geschah, als die Claims abgesteckt waren. Ich habe versucht ein Buch zu schreiben, dass sie dahingehend von anderen Büchern abhebt, dass es nicht nur Geschichte erzählt sondern auch erklärt warum bestimmte Produkte erfolgreich waren, also auf die Technik eingeht.

Die 2014 erschienene zweite Auflage wurde aktualisiert und leicht erweitert. Die umfangreichste Änderung ist ein 60 Seiten starkes Kapitel über Seymour Cray und die von ihm entworfenen Supercomputer. Bedingt durch Preissenkungen bei Neuauflagen ist es mit 19,90 Euro trotz gestiegenem Umfang um 5 Euro billiger als die erste Auflage. Es ist auch als e-Book für 10,99 Euro erschienen.

Mehr über das Buch auf dieser eigenen Seite.

Hier geht's zur Gesamtübersicht meiner Bücher mit direkten Links zum BOD-Buchshop. Die Bücher sind aber auch direkt im Buchhandel bestellbar (da ich über sehr spezielle Themen schreibe, wird man sie wohl kaum in der Auslage finden) und sie sind natürlich in den gängigen Online-Plattformen wie Amazon, Libri, Buecher.de erhältlich.


© des Textes: Bernd Leitenberger. Jede Veröffentlichung dieses Textes im Ganzen oder in Auszügen darf nur mit Zustimmung des Urhebers erfolgen.
Sitemap Kontakt Neues Hier werben Bücher vom Autor Buchempfehlungen Top 99