Home Computer x86 Prozessoren Site Map counter

Die x86-Entwicklung

Ergänzend zu den Artikeln über die einzelnen Prozessoren will ich in diesem Artikel die wesentlichsten Schritte in der Entwicklung de Architektur nicht nur nennen, sondern auch beschreiben will. Dabei will ich historische Parallelen ziehen, denn die meisten Entwicklungen wurden in Mikroprozessoren nur übernommen aber schon früher gemacht. Es geht dabei um die Hardware Architektur nicht die Erweiterung der Befehle (16 → 32 → 64 Bit Architektur)

Intel 8086: Prefetch

Der 8086 hatte neben der 16-Bit Architektur zwei Neuerungen die einander bedingten. Das erste war der Aufbau in zwei Einheiten, der Bus Interface Unit (BIU) und der Execution Unit. Das zweite war der Prefetch. Die Aufteilung in mehrere, unabhängige, Einheiten ist neu. Zwar gibt es bei jedem Prozessor Bereiche für eine bestimmte Funktion wie die ALU mit der gerechnet wird (Arithmetisch-Logische Einheit) oder der Befehlsdekoder, doch sie sind nicht unabhängig sondern stellen nur Stellen dar an denen eine bestimmte Verarbeitung stattfindet.

Bei unabhängigen Einheiten besteht der Vorteil, dass sie zumindest während eines Teils der Befehlsausführung parallel arbeiten und so die Ausführung verkürzen. Beim 8086 ermöglichte dies der Bus Interface Unit unabhängig von der Ausführungseinheit einen Prefetch durchzuführen. Darunter versteht man dass die BIU während ein Befehl ausgeführt wird, schon die nächsten Bytes ausliest und beim 8986 in einem 6 Byte langen Puffer speichert. Sie tat dies, wenn gerade der Datenbus frei war, also nicht Daten zur Verarbeitung gelesen oder geschrieben wurden.

Der Prefetch ist nützlich, weil Speicher langsamer als die Prozessoren ist. Das war schon beim 8086 so, wenn auch nicht sehr ausgeprägt. Wenn ein Prozessor den Wert einer Speicherstelle lesen will muss er erst die Adresse an den Speicherbaustein übermitteln, dann diesem über ein Signal übermitteln, das die Daten gültig sind und er auslesen will, dann muss er warten, bis der Speicherbaustein die Daten auf den Bus legt und signalisiert das sie abgerufen werden können. Diese Zeitspanne nennt man Zugriffszeit und sie kann eingespart werden, wenn die nächsten Befehle schon im Prozessor sind. Der Prefetch liest nun einfach automatisch die folgenden Bytes ein, weil in einem Programm meistens die nächsten Befehle auf den nächsten Bytes liegen. Damit wird die Ausführung beschleunigt.

Prefetch ist technisch einfach umzusetzen und wurde schon bei der Stretch 7030 eingesetzt. Die Technik wurde dann rasch Standard und die Buffer größer. Die IBM 7030 hatte einen Buffer von wenigen Bytes, das war 1961, die CDC 6600 vier Jahre später schon einen von 20 Befehlsworten (50-100 Befehle) und die Fähigkeit auch Sprünge innerhalb des Buffers durchzuführen und die Ausführungszeit für diese zu halbieren.

Intel 80286: Pipeline

Die erste wichtige Entwicklung war die der Pipeline. Eine Pipeline kann die Befehlsausführung sehr stark verkürzen. Jeder Prozessor hat einen Taktgeber und er erledigt pro Takt eine Aufgabe, die so bemessen sein muss, das sie in jedem Falle während eines Taktes ausgeführt werden kann. Wie viel dies ist, das hängt dann von der Hardware ab, z.B. den Gatterdurchlaufzeiten. Von den Einheiten die ein Prozessor hat, kann man den Maschinenzyklus definieren, der bei jedem Befehl durchlaufen wird. Dies sind:

Die Pipeline wurde zuerst vom IBM 360 System eingeführt und bald in anderen Computern übernommen. Sie parallelisiert diese Aufgaben. Ein Befehl durchläuft auf einer Pipeline die verschiedenen Abarbeitungsschritte und ist am Schluss abgearbeitet und die Pipeline wieder frei. So kann im Idealfall der nächste Befehl schon nach einem Takt angefangen werden, selbst wenn jeder Befehl mehrere Takte zur Ausführung braucht. Im Idealfall kann ein Rechner mit einer Pipeline pro Takt einen Befehl ausführen, egal wie lange die Ausführung des Befehls dauert. Der 80286 hatte eine dreistufige Pipeline, die wahrscheinlich den drei Elementarschritten Befehl holen - Dekodieren - Ausführen entspricht. Gegenüber dem 8086 wurde so die Ausführungszeit von 7,7 auf <3 Takten bei den meisten Befehlen reduziert.

Die Pipelines wurden dann immer länger um ein Maximum von 31 Stufen beim Pentium 4 zu erreichen. Da die Ausführung nicht immer linear ist vor allem bei Sprüngen im Programm die auch abhängig von Rechenergebnissen sein können gab es ab dem Pentium zur Unterstützung Branch Prediction Einheiten die basierend auf dem Verhalten in der Vergangenheit das Sprungziel vorhersagen, denn ist dieses falsch vorhergesagt so ist der gesamte Inhalt der Pipeline ungültig und ein Befehl kann nun zur Ausführung so lange brauchen wie eine Pipeline Stufen hat. Da es dafür Grnzen gibt sit seit dem Pentium die Größe der Pipeline wieder beim Abnehmen.

Intel 80386: Cache Unterstützung

Da der Speicher langsamer als die CPU ist, hat man schon frühzeitig den Cache eingeführt. Auch hier war das IBM Modell 360 der Vorreiter, der Cache wurde hier in den leistungsfähigsten Modellen eingeführt. Das Grundprinzip eines Caches ist sehr einfach, auch wenn sein Aufbau sehr komplex sein kann: Der Cache ist ein schneller, zwischen Prozessorkern und Speicher geschalteter Zwischenspeicher. Bei einem Zugriff auf den Speicher wird zuerst im Cache nachgeschaut ob die Befehle oder Daten dort vorliegen. Dann können sie aus dem schnellen Cache gelesen werden. So wird Zeit gespart. Da meistens man die Daten der folgenden Adressen braucht holt ein Cache vom Speicher mehr Daten ab als er aktuell braucht und füllt damit einen Block, die sogenannte Cacheline auf. Ein Cachecontroller ist verantwortlich für die Verwaltung des Speichers im Cache und für das Auffinden von Informationen.

Der 80386 hatte noch keinen eigenen Cache (dieser wurde beim 80486 auf dem Prozessor integriert), aber eine Unterstützung für einen externen Cachecontroller indem er vor einem Speicherzugriff die Adressen schon auf den Bus legte und über ein Signal dem Cachecontroller mitteilte, das er die Daten brauchte. Dieser hatte dann einen Takt lang Zeit im Cache zu suchen ob die Daten vorhanden waren bevor im nächsten Takt das eigentliche Abrufsignal vom Prozessor gesetzt wurde.

Der Cache war nötig, weil inzwischen die CPU so hoch getaktet war, dass bezahlbare Speicherbausteine zu langsam waren, der 80386 hätte schon beim niedrigsten Taktfrequenz bei jedem Befehl Wartetakte einlegen müssen. Der Cache steigerte die Geschwindigkeit so um rund 40%. Inzwischen geht es nicht mehr ohne Cache, weil Speicherbausteine sonst den Takt auf 100-125 MHz begrenzen würden. Sie machen heute den größten Teil der Chipfläche eines Prozessors aus. Bei einem Serverprozessor der Nehalem EX Architektur belegten Caches 60% der Chipfläche, die eigentlichen recheneinheiten nur 10%.

Eine zweite Neuerung ist der virtuelle Speicher. Er bietet für jedes Programm (von dem mehrere gleichzeitig aktiv sein können) den gesamten physikalischen Speicher zur Benutzung an. Dieser Adressraum wird in einen größeren Virtuellen Speicher gemappt, von dem wiederum nur Teile (bei 80386 von jeweils 4 KByte Größe) in den real existierenden Speicher geladen werden, der Rest steckte in einer Auslagerungsdatei auf der Festplatte. Dieses Konzept erleichtert die Speicherverwaltung für Multitasking Betriebssysteme und auch die Programmierung enorm. Das sie zeitgleich mit dem Cache eingezogen ist verwundert nicht, denn das Mappen von Seiten des benutzten Speichers in den realen und virtuellen Speicher erfolgt genauso wie das Verwalten von Cachelines.

Erstmals wurde virtuelle Speicher beim ATLAS Computer eingesetzt. Die VAX-Familie von Digital Equipment heiß nach dieser Technologie (Virtual Address eXtension)

Intel 80486: integrierter Fließkommaprozessor

Die bisherigen 80x86 Prozessoren hatten nur Befehle um Ganzzahlen zu verarbeiten. Dies galt auch für die ersten Computer. Wollte man Zahlen mit Nachkommastellen verarbeiten, so nutzte man oft Festpunktarithmetrik, man verschon für die Ausgabe einfach das Komma. Aus der Ganzzahl 123456789 wurde so die Festkommazahl 12345.67890. Diese Arithmetik ist schnell, hat aber Probleme. So ist in diesem Falle die Genauigkeit auf 5 Nachkommastellen begrenzt. Noch schwerwiegender: Es kann leicht bei Rechnungen zu einem Überlauf einer Vorkommastelle kommen z.B. bei der Multiplikation. Die Fließkommaaddition basierte auf der Trennung der Zahl in die Mantisse, den eigentlichen Wert ohne Angabe der Kommastelle als Ganzzahl und dem Exponenten, der die Zehnerpotenz angibt. Damit erreicht man eine höhere Genauigkeit und der Wertebereich in dem es keinen Überlauf gibt, ist viel größer. Bisher konnten die x86 CPU Fließkommazahlen nur per Software durchführen, was diese stark verlangsamte.

Die CDC 6600 führte 1965 erstmals Fließkommarechnungen in der Hardware ein. Die Recheneinheiten konnten erstmals die Fließkommarechnungen nativ ausführen. Damit eroberte dieser Rechner die Perfrormancekrone von IBM.

Einige Jahre nach Entwicklung des 8086 brachte Intel den 8087 auf den Markt der als Coprozessor Fließkommaberechnungen in der Hardware durchführen konnte. Seitdem gab es mehrere Generationen dieser Chips, die wegen des hohen Preises aber nicht viele Käufer fanden. Beim 80486 war der Koprozessor in den meisten Versionen integriert und in der Geschwindigkeit gesteigert worden. Damit wurden die Prozessoren vor allem im technisch wissenschaftlichen Bereich für Kunden attraktiver.

Pentium: Superskalare Architektur

Die Zahl der Funktionseinheiten war seit dem 8086 stark angestiegen. Bisher war es aber pro Aufgabe nur eine. Beim Pentium gab es zwei Recheneinheiten für Ganzzahlberechnungen (für Fließkomma nur eine). Damit konnte man bei voller Auslastung dieser Ganzzahlrechneinheiten die Geschwindigkeit gegenüber einer Einheit verdoppeln. Auch dieses Feature wurde von der CDC 6600 eingeführt, die sogar 10 Einheiten hatte, die allerdings sehr viel spezialisierter waren. Was der Pentium noch nicht konnte, war Abhängigkeiten aufzulösen. Sie begrenzen schlussendlich die Auslastung mehrerer Einheiten, da ein Befehl auf Daten eines vorrangehenden Befehles warten muss, Register gemeinsam genutzt werden oder sich Befehle überholen können (eine Addition z.B. schneller als eine Multiplikation ist) und so ein Befehl ein eigentlich später bestimmtes Ergebnis das schon vorliegt überschreiben kann.

Wenn dies nicht vorliegt dann können mehrere parallele Einheiten mehr als einen Befehl pro Takt verarbeiten, mit einer Pipeline ist bei einem Befehl pro Takt Schluss. Da nun auch die Pipeline ab der Dekodierung doppelt so umfangreich ist (eine pro Recheneinheit) wirkten sich Sprünge, bei denen der Pipelineinhalt ungültig sein konnte stärker aus und der Pentium bekam einen Puffer der die letzten Sprungadressen aufnahm. Aus diesem einfachen Puffer entwickelte sich bei den folgenden Generationen eine eigene Sprungvorhersageeinheit die vor allem bei Schleifen versucht ein Muster zu erkennen.

Heute sind in den Prozessoren fast alle Einheiten mehrfach vorhanden. Nicht nur Recheneinheiten, sondern auch Einheiten die Daten lesen oder Speichern, sonst wird der Transfer zum Speicher zum Flaschenhals. Auch Befehlsdekoder sind meist mehrfach vorhanden, weil sie sonst nicht alle Einheiten bedienen können.

Der Pentium war daher mit bestehender Software 1,7 mal schneller als sein Vorgänger bei gleichem Takt. Wollte man sein volles Potential ausnutzen musste man den Code neu übersetzen, wobei der Compiler die Befehle so gruppieren musste, dass die Einheiten möglichst voll ausgelastet wurden. Dann war der Code 2,3 mal schneller.

Pentium Pro: RISC-Kern und Out-of-Order Execution

Das Problem der Blockade von Befehlen wegen Abhängigkeiten wurde von Intel bei der nächsten Generation gelöst. der Pentium Pro hatte die Fähigkeit die Reihenfolge der Befehle bei der Abarbeitung zu ändern, dies wird "Out of Order Execution" genannt. Der Sinn ist relativ einfach: blockiert ein sich Befehl eine Einheit, so wurde einer ausgeführt der nominell später dran kommt, aber nicht von diesen oder anderen gerade ausgeführten abhängig ist. Dieses Feature ist sehr mächtig. Als Intel bei der ersten Atom-Generation es wegließ sank dessen Performance auf die eines 5 Jahre alten Prozessors ab. Die CDC 7600 setzte als erstes Out-of-Order Execution ein und steigerte so die Geschwindigkeit pro Takt gegenüber dem Vorgängermodell um den Faktor 3.

Bedeutender war jedoch die interne Änderung: die x86 Linie war eine klassische CSIC-Linie mit wenigen Registern und komplexen Befehlen. Intern wurden diese beim Pentium Pro nun in einfachere Befehle, sogenannte Mikroops übersetzt, manche Befehle in eine, andere Instruktionen in mehrere. Sie wurden von einem RISC Kern verarbeitet der viel mehr Register (128 gegenüber 15) hatte und so die Abhängigkeiten reduzierte. RISC war eine Architektur die es schon immer gab, aber Anfang der achtziger Jahre deutlich mehr eingesetzt wurde: sie basiert auf einfachen Befehlen, einem einfachen Befehls Format und vielen Registern. Das macht die Verarbeitung einfacher, man benötigt weniger Logikschaltungen für eine Funktion, dafür ist ein Befehl nicht so mächtig und man benötigt mehr Befehle um eine Rechnung auszuführen.

RISC Architekturen gab es schon früher viele. So kann man die CDC 6600/7600 und die Cray Supercomputer zu dieser Linie zählen. Bei den Mikroprozessoren haben MIPS, PowerPC und SPARC Prozessoren als RISC-Architekturen begonnen.

Pentium II: Vektorinstruktionen

Der Pentium II führte SSE ein. SSE (Streamings SIMD Extensions) erlauben die Bearbeitung von mehr als einem Wert mit einer Instruktion. Beim Pentium II waren es maximal vier 32 Bit Fließkommazahlen gleichzeitig. Dieses Prinzip wurde als Vektoroperationen 1976 von der Cray 1 eingeführt. Sie basiert auf der Einsicht, dass man die Zahl der Funktionseinheiten nicht über wenige Stück steigern kann, weil dann Abhängigkeiten auch durch Umsortieren die Geschwindigkeit begrenzen. Stattdessen verarbeitet ein Befehl mehrere Datenworte. Dies korrespondiert im Quelltext dem Iterieren in einer Schleife über einem Feld, eine Konstruktion die bei zahlreichen Problemstellungen vorkommt. Können diese Instruktionen eingesetzt werden (was von der Problemstellung, aber auch der Fähigkeit des Compilers abhängt), so vervierfachte sich bei der ersten SSE Generation die Leistung.

Eine zweite Änderung die mit SSE einzog, aber nicht nach außen hin sichtbar war, war die Verbreiterung der internen Datenwege auf heute 128 Bit. Damit transferieren Caches immer 16 Bytes auf einmal, auch intern haben die Verbindungen zwischen Dekodern, Recheneinheiten etc. diese Breite. Auch dies ist nicht neu: Schon früher nutzten Großrechner mehr Datenleitungen zum Speicher als die Befehlsworte breit waren, die CDC Star/203/205 z.B. 480 Bit breite Datenbusse bei 60 Bit breiten Datenworten. Damit kann man überhaupt die Vektordaten schnell verarbeiten, ansonsten geht der Zeitgewinn beim Rechnen wieder durch die längere Zeit für den Transfer der Daten verloren.

Pentium 4: Instruction Cache, SMT und Mehrkernprozessoren

Der Pentium veränderte die interne Architektur drastisch, doch eine wesentliche Änderung war nur der Trace Cache. Er nahm über 12.000 dekodierte Mikroops auf. Damit musste man bei kurzen Codestücken mit vielen lokalen Schleifen diesen Code nicht dauernd aus dem Cache holen und dekodieren sondern konnte auf diesen Cache zurückgreifen, was einige Benchmarks stark beschleunigte. Auch dieses Konzept gab es schon relativ frühzeitig bei vielen Rechnern, so der CDC 600, 7600 und Cray 1.

Um die Funktionseinheiten besser auszulasten, was mit mehr dieser Einheiten zunehmend schwieriger wurde, führte Intel Hyperthreading ein, das später die allgemeine Bezeichnung SMT (Simultaneous multithreading) erhielt. Bei dieser Technik werden dem Betriebssystem mehr Kerne gemeldet, als der Prozessor hat. Da das Betriebssystem immer sehr viele Threads auszuführen hat, mehr als es Kerne gibt kann ein weiterer Thread die unbenutzten Funktionseinheiten nutzen. Beim Pentium 4 lag der Gewinn bei durchschnittlich 10-15%. Diese Technik wurde erstmals von IBM im ASC 360 erprobt, in großem Stil aber erst Anfang der 2000-er Jahre von Mikroprozessoren wie dem Pentium oder Alpha 21264 eingesetzt.

Die späteren Pentium 4 CPU führten dann die ersten Mehrkernprozessoren (damals Doppelkern) ein. Hier teilen sich mehrere CPU den Zugriff zum Hauptspeicher und meist auch einen Cache (bei der ersten Dualcore-Generation noch nicht). Auf jedem kann ein eigenes Programm laufen. Dies macht einen Sinn in Umgebungen in denen es viele parallel laufende Aufgaben gibt (Server) oder wenn man ein Problem sehr gut in mehrere Teile aufteilen kann (Simulationen). Bei einem Single-User Betriebssystem wie Windows erlaubt es mehrere parallel laufende Programme oder Dienste ohne Verzögerung auszuführen. Mehrere Prozessoren gab es schon in den Siebziger Jahren, als Einzelprozessorsysteme kaum noch in der Geschwindigkeit steigerbar waren. In den Achtzigern nahmen sie stark an Popularität zu und es entstanden Großcomputer mit Hunderten von Prozessoren. Der erste massiv parallele Computer war die ILLIVAC IV von 1974. Bei den Supercomputern war die Cray X-MP der erste Mehrprozessorrechner.

Stand heute (2014: Haswell-Mikroarchitektur)

Die folgenden Generationen brachten zahlreiche Detailverbesserungen, aber seitdem hat sich der Grundaufbau nicht geändert. Die Architektur basiert heute wieder auf der der Pentium Pro die im Pentium II/III verbessert wurde. Die mit dem Pentium 4 eingeführte Netburst Architektur die auf hohe Taktraten ausgelegt war , konnte sich nicht durchsetzen. Die Konzepte wurden dagegen verbessert:

Artikel erstellt am 8.1.2015

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