Die glorreichen 10 – Computerarchitekturen (2)

Loading

So, heute geht es weiter mit dem zweiten Teil über die Fortschritte in der Computerarchitektur, die Geschwindigkeit brachten. Beide Teile bilden zusammen einen Artikel, den ich auch auf der Website online stelle – dort findet man ihn einfacher als im Blog, wo er nach hinten rutscht, auf der Startseite sieht man ja nur die letzten Artikel. Er schließt nahtlos an den ersten Teil von gestern an.

Speicherbänke

Eine zweite Lösung für das Problem, dass Speicher langsamer ist als gewünscht, ist die Unterteilung des Speichers in Bänke. Ein Rechner mit 4 Bänken ist so aufgebaut das die erste Bank immer Daten mit Adressen/4 speichert, die zweite Bank mit Adressen/4+1 … Das System ist klar. Wenn Code linear ausgeführt wird, wie es auch bei Caches vorhergesehen ist, greift der Prozessor nacheinander auf jede Bank zu, das heißt jede Bank hat viermal so viel Zeit für das Auslesen oder Schreiben von Daten und oft haben sie auch eine Logik die vorausschauend schon das nächste Datenwort ausliest und in einen schnellen Zwischenspeicher ablegt.

Speicherbänke waren vor allem in Großrechnern verbreitet, weil jede Bank eine eigene Adress- und Datenlogik braucht. Dann konnten es aber sehr viele sein. Seymour Cray lehnte z.B. Caches ab, dafür hatten seine Supercomputer bis zu 256 Speicherbänke. In den PC ist das Gegenstück ein Kanal, also ein Steckplatz für ein DIMM Modul. Ein PC aus dem Laden hat zwei oder vier Kanäle. Die Motherboards für Server haben mehr Steckplätze, meist 16 Kanäle. Der Grund ist relativ einfach – denn natürlich macht jeder Steckplatz das Motherboard teurer. Jeder Steckplatz benötigt Platz und eine eigene Verdrahtung. Wer mehrere Kanäle mit identischen Modulen bestückt, wird auch eine Geschwindigkeitssteigerung feststellen – durch die Caches hält er sich mit 5 bis 10 Prozent Geschwindigkeitsgewinn bei einem Desktop-PC aber in Grenzen. Bei Servern ist ein positiver Nebeneffekt, das man so nicht nur die Geschwindigkeit steigert, sondern man bei 16 Kanälen natürlich auch 16 DIMM Module einstecken kann und so über mehr Arbeitsspeicher verfügen kann. Der kann bei einem Server durchaus der Hauptkostenfaktor sein.

Virtuelle Adressierung

Ich bleibe beim Thema Speicher und Adressierung. Virtueller Speicher ist Speicher, den es physikalisch, also als Bausteine, nicht gibt. Welchen Sinn macht er dann? Nun es gibt zwei Nutzen. Zum einen kann ein Prozessor einen großen Adressraum bieten, denn man aber gar nicht ausnutzen kann. Als 1986 der 80386 Prozessor erschien war er der erste in seiner Reihe von Intel mit einem 32 Bit Adressraum, also 4096 MByte Speicher. Die ersten Systeme, die mit ihm erschienen hatten aber nur 4 MByte Speicher. 4 Gigabyte wären weder finanzierbar gewesen, noch mit der aktuellen Generation von DRAM-Chips (die 1 Megabit speicherte) realisierbar. In Zusammenarbeit mit dem Betriebssystem konnte aber eine Anwendung tatsächlich über diesen Speicher verfügen. Das Betriebssystem lagerte dazu Teile des Speichers auf Festplatte aus und zwar die Teile die am längsten nicht genutzt waren. Die Vorgehensweise ähnelt also dem Cache. Der Arbeitsspeicher ist praktisch ein Cache des virtuellen Speichers.

Die zweite Funktion betrifft das Multitasking. Das ist ja heute der Normalfall. Jede Anwendung wird aber von einem Compiler so erstellt, dass sie immer an einer festen Basisadresse beginnt. Die Logik, die den Speicher in Seiten unterteilt und diese bei Bedarf auslagert verändert auch die Adressierung von Anwendungen. Die Anwendung sieht einen logischen Speicher, genau so als wäre sie alleine vorhanden. Die virtuelle Speicheradressierung übersetzt diese Adressierung in eine physikalische Adressierung, platziert mehre Anwendungen, die alle meinen, sie beginnen bei einer festen, überall gleichen Adresse in unterschiedlichen Bereichen des Speichers und schottet sie voneinander ab.

Ohne virtuelle Adressierung wäre kein Multi-Tasking (Multi-User) Betriebssysteme möglich. Sie wird auch heute noch eingesetzt, auch wenn die meisten PC genügend Arbeitsspeicher haben. Früher war dies anders. Wer noch zu Windows 3.1 Zeiten arbeitete, kannte das Phänomen: sobald der Arbeitsspeicher erschöpft war und Windows begann Daten aus dem physikalischen Speicher in den virtuellen Speicher (eine Datei namens pagefile.sys, die gibt es bis heute im Stammverzeichnis C:\) auszulagern wurde die Anwendung sehr langsam.

Superskalarität

Schon früh in der Computerentwicklung reichte eine Pipeline nicht mehr aus um die Geschwindigkeit zu erhöhen. Der Flaschenhals bei den Prozessoren waren nun die Ausführungseinheiten. Die meiste Zeit des Zyklus aus Fetch-Decode-Exevute (siehe Teil 1) brauchte der letzte Teil. Die Lösung war die Ausführungseinheiten mehrfach vorzuhalten, wenn eine belegt war so wurde die nächste genutzt. So konnte man mehr als einen Befehl pro Takt abarbeiten, mit einer Pipeline ist es maximal einer. Später wurde dann auch der Dekoder mehrfach ausgelegt. Die Alder Lake Mikroarchitektur von Intel – nicht die neueste, aber noch im Handel unter der Bezeichnung iCore-12xxx – hat zum Beispiel nicht weniegr als 37 Ausführungseinheiten. Eingeführt hat dies Seymour Cray bei der legendären CDC-6600 Mitte der Sechziger Jahre. Intel zog 30 Jahre später mit dem Pentium nach. Die Bezeichnung klingt etwas komisch, kommt aber aus der Vektormathematik. Ein Skalar ist dort ein einzelner Wert also eine Zahl im Gegensatz zu einem Vektor, einem ein- oder mehrdimensionalen Feld auch Array oder Matrix genannt.

Vektoren

Auch die nächste Entwicklung wird mit Seymour Cray verbunden, wurde aber zeitgleich auch woanders erfunden, doch Crays Konzept war das erfolgreichste. Eine Vektorarchitektur gehört zu dem Konzept von SIMD – Singe Instruction, Multiple Data. Dahinter steckt die Erkenntnis das in vielen Anwendungen in Technik und Wissenschaft ganze Felder von Daten auf die gleiche Weise bearbeitet werden. In einer Schleife iteriert der Code zum Beispiel über ein Feld und führt bei jedem Element die gleiche Berechnung durch. Der Code ist dabei immer gleich, aber die Daten wechseln. Bei SIMD werden daher mit einer Instruktion mehrere Daten verarbeitet. Bei Crays Supercomputer waren das spezielle Vektorregister die 64 Werte fassten, bei AVX dem heutigen Gegenstück bei Intel/AMD ist es ein bis zu 512 Bit langer Wert, der der Instruktion folgt. Dieser wird dann im mehrere 64 oder 32 Bit lange Fließkommazahlen unterteilt. Analog funktionieren auch die KI-Beschleuniger, die neuere Prozessoren haben, nur sind bei ihnen die Werte die verarbeitet werden noch kleiner nur 16 oder 8 Bit breit. Der Vorteil: AVX kann, wenn man die 512 Bit z. B. in 16 x 32 Bit unterteilt 16 Werte in der gleichen Zeit bearbeiten, in der sonst nur ein Wert durchgeschleust wird. Das ist auch ein Grund warum Prozessoren heute so viele Ausführungseinheiten haben, denn für jeden Wert braucht man natürlich eine Einheit, die die Berechnung durchführt.

Out-of-Order Execution

Ich habe schon im ersten Teil dieses Artikels die Pipeline erwähnt, die dafür sorgte, dass eine CPU mehr als eine Anweisung gleichzeitig ausführen kann. Das hat aber Grenzen. Nehmen wir die einfache Berechnung A = B + C * D. Nach den Rechenregeln („Punkt vor Strich“) wird zuerst C * D berechnet und dann das Ergebnis zu B addiert. Solange dieses Ergebnis aber nicht feststeht, muss die Addition warten. Das hält besonders den Ablauf auf, weil wie jeder vom Kopfrechnen weiß, die Multiplikation länger dauert als die Addition, das ist auch bei Computern so. Bei einer „In-Order“ Architektur hält diese Anweisung also den Ablauf auf.

Bei einer Out-of-Order Architektur wird die CPU nun den folgenden Code analysieren und nach Befehlen suchen, die unabhängig vom Produkt C*D sind und diese ausführen, also vorziehen oder wie der englische Begriff aussagt die Reihenfolge umstellen. Das bringt einen ziemlichen Performancesprung weil diese Situationen doch sehr häufig im Maschinencode vorkommen. Heute haben alle Prozessoren von Intel und AMD dieses Feature außer die ganz billigen Atom-Prozessoren von Intel. Eingeführt wurde es bei dem Pentium Pro Prozessor, mit dem Intel vor allem im Bereich der Großrechner und Server Fuß fasste, aufgrund seines Preises sich im Desktop-Bereich aber nicht durchsetzen konnte.

Damit verbunden, aber nicht das Gleiche, ist ein zweites Verfahren namens Branch Prediction. Im Code gibt es viele bedingte Sprünge. Alle Schleifen in einer Hochsprache enden in einem solchen Sprung, wo wieder zum Schleifenanfang gesprungen wird, wenn eine Bedingung erfüllt ist oder eben nicht. Ebenso führen If-THEN Abfragen in einer Hochsprache zu bedingten Sprüngen. Diese sind für die Ausführung fatal. Denn anders als bei Out-of-Order kann man nun keinen Befehl vorziehen, ja da die Ausführung an einer anderen Stelle fortgesetzt wird, kann es sein, dass Dutzende Befehle die in der Pipeline stecken, nun alle ungültig sind. Der Pentium 4 Prozessor hatte wegen seines hohen Taktes eine sehr lange Pipeline und war daher sehr anfällig gegen einen Sprung, der nicht dahin ging, wo er ihn vermutete. Um dies zu vermeiden, haben alle Prozessoren heute Sprungvorhersage-Logiken. Sie versuchen vorherzusagen, wohin der Sprung geht, indem sie die Befehle vor dem Sprung, deren Ergebnis die Bedingung für den Sprung definiert analysieren und schon mal probeweise ausführen.

Intel und die Fortschritte

Hier in der langen Geschichte der intel Prozessoren die Prozessoren wo eines der obigen Features erstmals auftrat:

Prozessor … führte ein
8086 Microcode
80286 Pipeline
80386 Cacheunterstützung, aber Cache noch extern
Virtuelle Adressierung
80486 Interner Cache mit voller Prozessorgeschwindigkeit
Pentium Superskalarität für die Integerberechnungen, Branch Prediction Buffer
Pentium Pro Out-of-Order Execution, RISC
Pentium II Superskalarität (SSE, später zu AVX erweitert)
Pentium 4 Hyperthreading, Mehrkernprozessoren (bei der letzten Generation, Pentium D „Smithfield“)

Noch eine kleine Erläuterung zu „RISC“ beim Pentium Pro. Der x86 Code und der nun aktuelle IA64 Code ist natürlich in CISC-Code. Doch auch Intel erkannte die Vorteile von RISC und hat seit dem Pentium Pro eine Art Übersetzer im Prozessor integriert. Dieser ersetzt eine CISC Anweisung durch eine Folge von elementaren RISC Anweisungen im Intel Jargon „Micro-Ops“genannt. Diese Micro-Ops sind schneller verarbeitbar und auch einfacher an die vielen Ausfuhreinheiten verteilbar. Heutige Prozessoren von Intel haben sogar einen eigenen Cache für diese Micro-Ops im Prozessor.

Das Hyperthreading beim Pentium 4 war eine Vorstufe eines Mehrkernprozessors. Ein Mehrkernprozessor hat mehrere Prozessorkerne, also alle Bestandteile eines Prozessors sind mehrfach vorhanden. Beim Hyperthreading, (allgemeine Bezeichnung Symmetrisches Multithreading – SMT) werden nur die unbenutzten Funktionseinheiten durch einen zweiten Thread ausgelastet. Das bringt etwas mehr Performance, aber deutlich weniger als ein zweiter Kern, weil Dekoder und Speicherinterface und Cache natürlich nicht mehrfach vorhanden sind.

One thought on “Die glorreichen 10 – Computerarchitekturen (2)

  1. „Ohne virtuelle Adressierung wäre kein Multi-Tasking (Multi-User) Betriebssysteme möglich.“

    Das stimmt so nicht. Multitasking ist ganz ohne virtuellen Adressraum umsetzbar, z.B. in AmigaOS. Dort wurden die absoluten Adressen beim Laden an die aktuelle physische Adresse angepasst, so das Programme an jede beliebige Adresse geladen werden konnten. Es gab da zwar kein Multi-User aber auch das ist nicht vor virtuellen Adressen abhängig. Virtuelle Addressierung ermöglicht die Abschottung von Prozessen gegeneinander, das ist aber weder für Multitasking noch Multiuser zwingend notwendig.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.