close

Anmelden

Neues Passwort anfordern?

Anmeldung mit OpenID

3.Teil - BTU Cottbus

EinbettenHerunterladen
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
3.
Leistungsberechnung und Leistungsbewertung von Rechnern und Prozessoren
3.1
Einführung
Wie schwierig es ist, die Leistungsfähigkeit eines Rechners festzustellen, kennt fast jeder Anwender.
Er stellt nämlich fast immer nur die Leistung einer bestimmten Rechnerkonfiguration unter
bestimmten Nebenbedingungen und für spezielle Software fest.
In der Praxis hat die Leistungsbewertung von Rechnern mehrere kritische Funktionen.
Einmal ist es interessant, zu wissen, welcher Teil des Rechners denn tatsächlich bezüglich einer
bestimmten Anwendung den „Flaschenhals“ in der Leitung bildet. Eine ungezielte Aufrüstung aller
Rechnerteile im Fall eines Engpasses in der Leistung wäre weder wirtschaftlich noch sinnvoll.
Natürlich muß man auch die Leistung verschiedener Rechner über „Benchmarks“ vergleichen
können.
Es ist alles andere als einfach, für einen Rechner ein in der Breite aller Anwendungen relevantes
Leistungsmaß anzugeben. Zunächst hängt jedes Leistungsmaß von der Art der Anwendungen und
der Abstimmung mit dem und auf den Befehlssatz des Prozessors ab. Man kann einmal Rechner so
betrachten, daß die Leistung schon ausreicht, wenn der Anwender nicht nervös wird. Für Leute, die
den PC nur als Schreibmaschine und für Computerspiele verwenden, ist das schon fast ein gutes
Maß. Andererseits spielen Rechner zunehmend als Steuerglieder in Echtzeitanwen-dungen eine
Rolle, und dann ist die Leistungsabschätzung ein wichtiger Punkt des Systement-wurfs.
3.2
Hardware-bezogene Leistungsmaße
3.2.1 Einflußgrößen und einfache Leistungsmaße
Für eine Leistungsabschätzung bezüglich eines bestimmten Programms ist es zunächst notwendig, zu
wissen
− welche Maschinenbefehle das Programm wie häufig nutzen wird
− wie viele Taktzyklen ein Befehl zur Abarbeiung braucht.
Die mittlere Operationszeit kann man dann nach von Neumann angeben zu:
n
T: = Â ti * pi.
i=1
Dabei ist T die mittlere Operationszeit, ti ist die Operationszeit des i-ten Befehls, z. B, in Taktzyklen
gemessen, und pi ist die relative Häufigkeit des Befehls im Befehlssatz.
Hier muß man je nach Typ des Rechners noch Zuschläge einführen. Ein Befehl muß zunächst geholt
und entschlüsselt werden, bevor er ausgeführt werden kann.
Als einfache Formel für die Leistung eines Rechners kann gelten:
L: = 1 / (Taktzyklen pro Durchschnittsbefehl * Taktzyklen in Mikrosekunden).
Die gängige Maßeinheit ist hier MIPS (Millionen Instruktion pro Sekunde).
Für die Taktzyklen pro Durchschnittsbefehl benutzt man auch die Abkürzung CPI (Zyklen pro
Instruktion).
1
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Die Arten von Befehlen und ihre relative Häufigkeit, gemittelt über eine Reihe von Anwendungen,
kann man etwa wie folgt angeben:
Befehlsklasse
Relative Häufigkeit
Load / Store
31,2 %
Verzweigungsbefehle
16,6 %
Integer- Addition / Subtraktion
6,1 %
Vergleichsbefehle
3,8 %
Gleitkomma- Add. / Subtr.
6,9 %
Gleitkomma-Multiplikation
3,8 %
Gleitkomma-Division
1,5 %
Integer-Multiplikation
0,6 %
Shift-Befehle
Logische Befehle
Adressierung mit Index
Andere Befehle
4,4 %
1,6 %
18,0 %
5,3 %
Abb. 3.1: Relative Häufigkeit von Befehlen (nach Siewiorek et al. 1982)
Die relative Häufigkeit von Befehlen, welche das Laden von Registern aus dem Speicher betreffen,
ist wohl von allgemeiner Gültigkeit (da ja auch jeder Befehl erst geladen werden muß).
Ansonsten ist nur allgemein gültig, daß selbst bei komplexen Befehlssätzen ca. 90% der
vorkommenden Operationen von ca. 10% des Befehlssatzes abgedeckt werden und nur 10% der
Operationen an "exotische" Befehle gehen.
Ob "exotische" Befehle benutzt werden, hängt darüber hinaus vom Compiler ab.
Viele Compiler kennen gar nicht den vollen Befehlssatz des Zielprozessors, lassen also den
Befehlssatz in Teilen ungenutzt. Das ist eine Erkenntnis, welche die Entwicklung von RISCMaschinen mit unterstützt hat.
Die Untersuchungen von Hennessy und Patterson geben bezüglich der Häufigkeit von Befehlen ein
wesentlich differenzierteres Bild.
Zunächst kommen viele Programme ohne Gleitkommabefehle und ohne arithmetische Befehle mit
doppelter Präzision aus. Dies dürften z. B. alle Programme zur Textverarbeitung sein. Auch logische
Operationen sind dort eher selten. Es werden dagegen Befehle verwendet, die sich explizit auf
Zeichen (Characters) oder Zeichenketten (Character strings) beziehen. Intel-Prozessoren besitzen
einige spezielle Characterbefehle.
Simulatoren wie SPICE benutzen dagegen in großem Umfang Befehle mit Variablen vom Typ real,
float oder double precision. Gerade hier kommt es damit auf eine ausreichende Bitbreite (mindestens
32) für effiziente Speicherzugriffe und auf die Leistungsfähigkeit von Arithmetik-einheiten, also z. B.
Addierern und Multiplizierern, an. Intel-Prozessoren, die bezüglich der Verarbeitung von
Integerdaten z. B. langsamer sind als kompatible AMD-Prozessoren, haben typischerweise
leistungsfähigere Floating-Point-Einheiten. Da Graphikprogramme oft die schnelle Umrechnung von
Koordinaten benötigen, spielt die Gleitkommaleistung auch dort eine wichtige Rolle.
Für die digitale Signalverarbeitung spielen Operationen eine wichtige Rolle, welche eine
Multiplikation einer Variablen und die Addition einer weiteren Variablen beinhalten. Um Befehle
dieser Art ist deshalb auch der Pentium erweitert worden (der IBM Power PC hatte sie schon
vorher). Prozessoren für die digitale Signalverarbeitung (DSPs) sind auf solche Befehle optimiert.
2
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Insgesamt kann eine Leistungsangabe in MIPs für einen Rechner, oder auch die Angabe in MFLOPs
(Mio. Fließkommaoperationen pro Sekunde) nur ein grober Anhaltspunkt für die Leistungsfähigkeit
eines Rechners sein. Sie taugt z. B. ganz und gar nicht zur Vorhersage, ob ein bestimmter Rechner
eine bestimmte Aufgabe in einer vorgegebenen Zeit erledigen kann oder nicht.
Wir müssen von jetzt ab zwei verschiedene Aufgaben unterscheiden:
− Definition einer "groben" Leistungsangabe eines Rechners zu Vergleichszwecken
− Voraussage, Messung oder Abschätzung des Zeitaufwandes für eine bestimmte Aufgabe.
Der letztere Aspekt gewinnt für Rechner in Realzeitanwendungen große Bedeutung.
3.2.2 Einflußgrößen und Berechenbarkeit
Für die Ausführungszeit eines Programms auf einem Rechner spielen also eine wichtige Rolle:
−
−
−
−
der verfügbare Befehlssatz
die Nutzung des Befehlssatzes durch den Compiler
die Leistungsfähigkeit arithmetischer Einheiten
die Leistungsfähigkeit des Speichersystems.
Bezüglich der Ausführungszeit desselben Codes auf unterschiedlichen Maschinen (sogar mit nominal
etwa gleicher Leistungsfähigkeit) kann man also signifikante Unterschiede erleben.
Will man also die Ausführungszeit eines Programms wirklich messen, so benötigt man dazu im
allgemeinen die reale Systemkonfiguration in Hardware und Software. Dies reicht aber oft immer
noch nicht aus. Viele Programme enthalten von Eingangsdaten abhängige Verzweigungen.
Programm
(z. B. in C )
Befehlssatz
Compiler
Binärcode
Speicher
System
DatenAblauf
satz
Betriebssystem
Ablaufzeit
Abb. 3.2: Einflußgrößen für Ablaufzeiten von Programmen
Selbst dann, wenn man dasselbe Programm auf demselben Rechner mit demselben Datensatz
mehrfach ablaufen läßt, kann es zu unterschiedlichen Ablaufzeiten (elapsed times) kommen. Wenn
nämlich der Rechner ein Multi-Usern / Multi-Tasking-Betriebssystem (wie UNIX) besitzt,
beeinflussen sich die unterschiedlichen Prozesse gegenseitig. Das Betriebssystem steuert nämlich
auch Auslagerung von Datenblöcken (die auch Programmteile enthalten können) zwischen
Hauptspeicher und Plattenspeicher.
3
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
M inimalkonfiguration
Komplexe Speichersystem
Prozessor
Prozessor
BIOS-ROM
Register
Register
Prozessor
RAM
(Daten)
ROM
1st level Cache
(Programm)
1st level Cache
(Daten)
(Programm)
Prozessor
2nd Level Cache
Chipsatz
Hauptspeicher
Betriebssystem
Plattenspeicher
Abb. 3.3: Speicherhierarchie in Minimalversion (beim Mikrocontroller) und beim Personalcomputer
Ziemlich zuverlässig möglich ist die Vorhersage der Ablaufzeit noch bei Rechnersystemen mit
einfacher Speicherkonfiguration, wie sie bei Mikrocontrollern üblich ist: Das Programm ist in einem
ROM, PROM oder EROM-Speicher abgelegt, für die Speicherung von Daten ist ein meistens kleiner
RAM-Speicher (von bis zu ca. 100 KByte) vorhanden. Ein Betriebssystem existiert nicht oder nur in
sehr einfacher Form dann, wenn eine Multi-Tasking-Fähigkeit benötigt wird. (Es gibt spezielle sehr
einfache Echtzeitbetriebssysteme). Man kommt auch mit gerade mal zwei Speicherebenen aus.
Typisch für Mikrocontroller ist die Verfügbarkeit von RAM- und ROM (manchmal auch PROM
oder EPROM-) Speicher auf demselben Chip, der auch die CPU enthält.
In der Regel sind hier gute Messungen und Abschätzungen über Codelaufzeiten möglich.
Problematisch sind nur Betriebsarten mit häufiger Interruptverarbeitung.
Ein viel komplexeres Problem ist die Leistungsabschätzung und auch die Leistungsmessung schon
beim Personal Computer (PC). Einschließlich der Prozessorregister sind hier fünf Speicherebenen
vorhanden: 1st-Level und 2nd Level-Cache, Hauptspeicher und Platte (als Dauerspeicher und für
Auslagerungsdateien).
Die Organisation dieses Speichersystems wird auch in verteilter Weise organisiert:
Das Laden und Speichern von Registern aus dem 1st Level Cache besorgt der Prozessor. Für den
Verkehr zwischen 1st- und second-Level-Cache ist der Chipsatz auf der Hauptplatine des PCs
notwendig, ebenso für den Austausch zwischen Cache und Hauptspeicher. Den Datenaustausch
zwischen Hauptspeicher und Festplatte organisiert allerdings das Betriebssystem.
In solchen Systemen geht die Organisation der Caches stark in die Leistungsbewertung ein. Ob, unter
welchen Nebenbedingungen und wie häufig "Cache Misses" auftreten, also das Nachladen des Cache
aus dem Hauptspeicher notwendig wird, ist nicht einfach vorhersagbar.
Deterministische Strategien für die Cache-Organisation, welche eine Vorhersage des Verhaltens
erlauben, befinden sich erst in der Entwicklung.
Natürlich ist für solche komplexen Speichersysteme ein Interruptbetrieb geradezu zerstörerisch:
Eine Interruptbearbeitung kann bedeuten, daß der Inhalt aller Prozessorregister im Hauptspeicher
gesichert wird und daß alle Caches "ausgeräumt" werden. Das Interruptverhalten von solchen
4
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
komplexen Strukturen kann so "irre" werden, daß man oft nicht mal einen "worst-Case“-Grenzwert
für die Bearbeitungszeit angeben kann.
3.2.3 Komplexere Leistungsmodelle
Zur Leistungsbewertung ist es zunächst notwendig, auch das Speichersystem und dessen Bandbreite
einzubeziehen.
Im einfachsten Fall gehen ein:
CPI:
TI:
S:
Ts:
Taktzyklen pro Durchschnittsbefehl
Taktzykluszeit [s]
Speicherbedarf pro Durchschnittsbefehl [Bit]
Speicherzugriffszeit [s / Bit].
Die Formel für die Leistungsbestimmung ist dann wie folgt anzugeben:
1 / LeistungsBN : = CPI * TI + S * Ts
Beispiel:
Für einen CISC-Rechner wurde beispielsweise ein Speicherbedarf von durchschnittlich 8,6 Bytes
(entsprechend 68,8 Bits) pro Durchschnittsbefehl ermittelt. Davon entfallen 3,3 Bytes auf den Befehl
selbst und 5,3 Bytes auf die adressierten Daten (Operanden, Ergebnisse). Für einen den 32-BitCISC-Prozessor wurden außerdem im Mittel 6,4 Taktzyklen pro Befehl ermittelt (CPI).
Beträgt nun der Taktzyklus 60 ns und liegt die Speicherzugriffszeit bei 178 ns für ein 32-Bitwort
(entsprechend 5,5 ns pro Bit), so erhält man für diesen Rechner (P1):
1 / LeistungsBN = 6,4 * 60 * 10-9 [s] + 68,8 [Bit] * 5,5 * 10-9 [s / Bit]
= 7,624 * 10 -7 [s].
LeistungsBN = 1,312 * 106 [1/s].
Eine solche Abschätzung taugt dann zum groben Leistungsvergleich zwischen unterschiedlichen
Rechnern. Die hier gefundene Leistungszahl gilt etwa für 32-Bit-Supermini-Computer von 1980.
Man kann jetzt auch eine minimal erforderliche Speicherbandbreite angeben:
Speicherbandbreite [Byte/ s] = Leistung [1/s] * Speicherbandbreite pro Durchschnittsbefehl [Byte].
Beispiel:
Für einen 32-Bit CISC-Prozessor P2 mit einem CPI von 4,5 und einer Zykluszeit von 3,3 ns (30
MHz) errechnet man zunächst die Leistung in MIPS:
LeistungMIPS = 1 / (4,5 * 33,3 * 10-9 [s] = 6, 673 MIPS.
Speicherbandbreite:
BandbreiteP2 = 6, 673 Millionen Befehle [1 / s] * 8,6 [Byte] = 57, 39 [MB / s].
5
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Soll also der Prozessor ohne Wartezyklen arbeiten können, so muß er mit einer Transferrate von 57
MB pro s auf den Speicher zugreifen können.
Jetzt geht die Organisation des Speicherzugriffs ein:
Ein 32-Bit-Standardprozessor wird pro Zugriff auch 32 Bit über einen 32-Bit-Bus zugreifen können.
Damit wird es pro Sekunde 14, 35 Mio. Speicherzugriffe benötigen. Dies entspricht einer Zeit von
etwa 70 ns pro Zugriff. Das sind dynamische RAMs der mittleren Preisgruppe.
Ein Prozessor mit 6,7 MIPs ist heute durchaus nicht mehr "Spitze der Technologie", sondern gehört
eher zu auslaufenden Typen (so etwa 80486).
Nehmen wir einen leistungsfähigeren Prozessor als Beispiel:
Jetzt sei ein echter RISC-Prozessor mit nur noch 1,5 Taktzyklen pro Befehl betrachtet. Der erreicht
dann bei gleicher Taktfrequenz (33 MHz) eine Leistung von 20 MIPs. Die notwendige
Speicherbandbreite liegt unter der Bedingung, daß wir wieder 8,6 Bytes Speicher pro Befehl
benötigen, bei 172 MByte / s.
Ist der Speicherbus wieder 32 Bit breit, so bleiben für die Zugriffszeit gerade mal 23 ns übrig.
Und das ist mit konventionellen dynamischen RAMs allein nicht mehr zu schaffen.
SDRAMs (synchrone DRAMs) der neuesten Generation mit gerade mal 12 ns pro Speicherzugriff
schaffen aber, zumindest potentiell, Abhilfe.
Ein paar Möglichkeiten, den Durchsatz auch mit langsameren RAM-Bausteinen zu schaffen, sollen
vorgestellt werden.
Zunächst war es bei Mikroprozessoren üblich, gemeinsame Busse für Daten und Adressen zu
verwenden. Leistungsfähigere Prozessoren verwenden aber getrennte (32-Bit-) Busse für Daten und
Adressen.
Bewährte Methoden zur Erhöhung der Speicherleistung sind:
− Getrennte Busse für Daten und Adressen
− Adreßpipelining
− Burst-Modus
− Interleaved Memory
− Caches
− Speicherhierachien.
3.2.4 Schnellere Speicherorganisation für höhere Speicherbandbreite
Als erste Variante soll das Adreßpipeling vorgestellt werden.
Bei einem Lese- oder Schreibzugriff wird zunächst eine neue Speicheradresse an den Adreßbus
angelegt. Gleichzeitig liegt das Datum vom letzten vorhergehenden Speicherzugriff auf dem
Datenbus schon seit einem halben Taktzyklus an. Die neue Adresse wird in einen Zwischen-speicher
(Latch) übergeben und kann von dort schon vor der Beendigung des vorhergehenden Lesezyklus
dekodiert werden.
In der Zeit der Dekodierung kann vom Prozessor bereits die nächste Adresse angelegt werden.
Durch diesen "überlappenden" Betrieb steht insgesamt ein halber Maschinenzyklus länger für die
Dekodierung zur Verfügung. Man erreicht mit gleich schnellen Speicherbausteinen etwas höhere
Leistung, die sich aber im Rahmen von weniger als 50% bewegt.
6
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Die EDO-RAMs verwenden im Prinzip denselben Trick: Sie lassen am Ausgang ein Datum länger
anstehen, während die nächste Adresse schon dekodiert wird.
Adressbus
(ADR2)
Zwischenregister
ADR 2
Hauptspeicher
CPU
ADR1
Adressdekodierung
ADR2
Datenbus
(Daten von ADR1)
Abb. 3.4: Adreßpipelining
Wesentlich effizienter kann ein Speicherzugriff im Burst-Modus sein.
In diesem Fall wird Adressierungszeit dadurch eingespart, daß man zu lesende Information in
aufeinanderfolgenden Speicherzellen abgelegt hat und dieses auch "weiß"! Dann wird nur die erste
Adresse wirklich dekodiert, die nachfolgenden werden nur noch über Zusatzlogik, also z. B. einen
Zähler, generiert und an den Speicher weitergegeben. Wenn der Speicher dafür eingerichtet ist,. kann
man also nach einer vollen Dekodierung die folgenden Adressen mit wesentlich höherer
Geschwindigkeit nacheinander lesen.
Speicherzugriffe dieser Art sind bei PCs schon länger Stand der Technik.
Beispiel:
Beim Intel 80486 können in insgesamt 5 Taktzyklen jeweils die nächsten vier 32-Bit-Datenworte ab
einer Anfangsadresse geholt werden. Ist der Prozessor beispielsweise ein mit 50 MHz getakteter
80486 DX50, so ergibt sich als Speicherbandbreite:
Bandbreite 486 = 16 [Byte] / 5 * 20 * 10 -9 [s]
= 160 [MB/s].
Das bedeutet eine erhebliche Anforderung an die Bandbreite für den Datenbus.
Ohne Burst-Modus würde man für die vier Datenworte 8 Takte benötigen, was einer Speicherbandbreite von 100 MB/s entspricht.
Die Unterstützung von Übertragungen im Burst-Modus ist auch "Gemeingut" vieler RISCProzessoren. Dabei kann in der Regel die Länge der übertragenen Datensequenz beliebig sein. Dann
wird jeweils ein Speichercontroller über ein spezielles DATA-READY-Signal vom Prozessor bzw.
vom Chipsatz aufgefordert, die nächste Adresse durch Weiterzählen zu bestimmen.
In der Realität wird man natürlich dieses Prinzip nicht beliebig treiben können, da ja die Daten im
Hauptspeicher nicht "beliebig" stehen, sondern in voneinander getrennten und gegeneinander
geschützten Seiten (pages) oder Segmenten (segments) angeordnet sind.
Der dritte "Trick" ist das sogenannte "interleaved memory", auch als Speicherverschränkung
bezeichnet. Dazu werden die Speicherbausteine in sogenannten Speicherbänken angeordnet und
adressiert. Zwei Speicherbänke können jeweils überlappend adressiert und gelesen bzw. beschrieben
werden.
Beim PC konnte der Speicher des 80486-Prozessors in zwei Bänke organisiert werden. Mehr als vier
Speicherbänke machen bei PCs kaum Sinn. Dagegen sind bei Großrechnern viel größere Speicher
7
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
üblich, womit auch die Aufteilung in Speicherbänke mehr Sinn macht. Bei der CRAY Y-MP C90
sind bis zu 1024 verschiedene Speicherbänke möglich, die mit BICMOS-Chips bestückt sind.
Der Speicherzugriff wird jeweils in geeigneter Weise auf die Speicherbänke verteilt, also im
Extremfall wird für jede neue Adressierung eine neue Speicherbank angesprochen. Auch hier ist ein
Burst-Modus mit inkrementieller Adressenerhöhung üblich.
Trotzdem tritt jeweils dann, wenn eine neue Adressierung durchzuführen ist, eine nicht unerhebliche
Latenz auf.
Das Prinzip der getrennten Busse für Daten und Befehle hat sich weitgehend durchgesetzt. Man kann
die Speicherbandbreite einmal durch schnelleren Zugriff und schnellere Busse, aber auch durch
breitere Busse erhöhen.
Wer seinen PC unter Windows mit einem nur 16 Bit breiten Speicherzugriff betreibt, ist in der Regel
nur halb so schnell wie beim alternativen 32-Bit-Zugriff.
Die Prozessoren des Superrechners Cray Y-MP 90 benutzen gleichzeitig drei 128 Bit breite
Datenbusse für den Speicherzugriff.
Allgemeingut geworden ist inzwischen die Organisation von Prozessorspeichersystemen über
schnelle Zwischenspeicher (Caches, von franz. cacher-verstecken) zwischen den Registern des
Prozessors und dem Hauptspeicher. Dazu gibt es sowohl einstufige Chaches als auch hierarchisch
aufgebaute mehrstufige Caches. Diese werden mit statischen RAMs als den schnelleren, aber im
Vergleich zu dynamischen RAMs weniger dichten und deshalb wesentlich teureren Bausteinen
ausgerüstet.
Man unterscheidet gemeinsame Caches für Daten und Befehle von gemeinsamen Chaches. Während
in früheren Zeiten z. B. nur on-Chip-Caches für Befehle (wie beim 80486-Prozessor) üblich waren,
sind bei modernen RISC-Prozessoren und ab dem Pentium auch bei den Intel-Prozessoren getrennte
on-Chip-Caches für Daten und Befehle üblich. Der auf der Hauptplatine verwendete Second-LevelChache dient sowohl für die Zwischenspeicherung von Daten als auch von Befehlen.
Die Auslegung der Prozessoren selbst in PCs als Pipelineprozessoren (schon seit dem 80286) und
erst recht als superskalare Prozessoren (seit dem Pentium) hat die Anforderungen an die
Speicherbandbreite so stark gesteigert, daß Caches eine Notwendigkeit wurden. Z. B. erfordert eine
Auslegung eines Rechners mit einer n-stufigen Pipeline und als m-fach superskalarer Rechner eine im
"worst case"-Fall (für den Speicher) bzw. "best case" (für den Nutzer, wenn die Parallelität
ausgenutzt werden kann), eine Vervielfachung der Speicherbandbreite um den Faktor n*m.
CPU
BefehlsCache
CPU
DatenCache
Hauptspeicher
BefehlsCache
Hauptspeicher
Partition A
DatenCache
Hauptspeicher
Partition B
Abb. 3.5: Cache mit Harvard-Architektur
Beispiel:
Wir nehmen eine Harvard-Architektur mit getrenntem Befehls- und Daten-Cache an. Die Aufgabe ist
eine quantitative Aussage über die Leistung dieses Systems.
Variante 1:
8
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Wir gehen von einem CISC-Prozessor mit getrennten Bussen, 50 MHz Taktfrequenz und einem CPIWert von 2,0 aus. Dann müssen wir noch eine Annahme über die Häufigkeit der "Treffer" beim
Cache-Zugriff machen. Es ist vernünftig, anzunehmen, daß bei 95 % der Speicherzugriffe die Befehle
oder Daten im Chache vorhanden sind. Außerdem wird wieder angenommen, daß pro Befehl 8,6
Bytes an Daten bewegt werden müssen. Wir nehmen auch wieder an, daß pro Befehl im Mittel 3,3
Bytes für den Befehl selbst und 5,3 Bytes für Operanden / Ergebnisse benötigt werden.
Mit den bisher vorgestellten Formeln können wir dann angeben, daß der Prozessor eine Leistung von
25 MIPS hat und maximal 215 MB/s an Daten benötigt.
Mit einer nach Befehls- und Daten-Cache getrennten Architektur ist dann zweifellos der DatenCache höher beansprucht. Also werden wir diesen genauer betrachten.
Wenn pro Befehl 5,3 Bytes zu transferieren sind, so entspricht das einer maximal benötigten
Speicherbandbreite von 132,5 MB/s. Das entspricht bei 32 Bit einer Zugriffsgeschwindigkeit von
etwa 30 ns.
Dieser Zahlenwert ist mit dynamischen RAM-Bausteinen noch erreichbar.
Bei 5% aller Zugriffe ist angenommen, daß sich die Daten nicht im Cache, sondern im Hauptspeicher
befinden. Dementsprechend müssen nur 5 % der benötigten Daten, also 10,75 MB, pro Sekunde aus
dem Hauptspeicher geholt werden.
Das würde im Idealfall einer Zugriffszeit von 372 ns für den Hauptspeicher entsprechen. Das ist nicht
sehr viel. Man wird aber noch einen gewissen Zuschlag für die Organisation des Transfers zwischen
Hauptspeicher und Cache sowie zur Lösung von Konsistenzproblemen zwischen beiden Teilen
einplanen müssen.
Variante 2:
Nun idealisieren wir den Prozessor und nehmen bei einem Takt von 50 MHz an, daß pro Takt ein
Befehl ausgeführt wird. (Das kann tatsächlich passieren, wenn der Prozessor gepipelint oder
superskalar ist. Dann sind z. B. bei einer Pipelinetiefe von 5 und einem 4-fach superskalaren
Prozessor durchaus mehr als ein Befehl pro Takt möglich). Alle Befehle sollen eine Standardlänge
von 32 Bit haben. Da der Prozessor genügend Register zur Zwischenspeicherung von Ergebnissen
besitzt, lösen nur etwa 30% aller Befehle Speicheroperationen aus, sind also LOAD / STOREBefehle.
Bei manchen Maschinen können sich bereits infolge der Pipelinearchitektur (genauer gesagt, der
Phasenpipeline) die Phasen des Holens von Befehlen und der Rückschreibens von Daten überlappen.
Damit dies nicht passiert, sind getrennte Zugriffspfade auf den Speicher für Befehle und Daten
sinnvoll bis notwendig. Ansonsten ist mit ca. 10% Leistungsverlust durch Zugriffskonflikte zu
rechnen.
Nun wird es notwendig, 50 Mio. Befehle pro Sekunde zu verarbeiten, d. h. bei 32 Bit pro
Befehlswort einen Transfer von 200 MByte/s durch den Befehls-Cache.
Dazu müßte der Cache nun eine Zugriffszeit von 20 ns haben. Das ist mit schnellen SRAMBausteinen (und sogar mit den neuen SDRAMs!!) möglich.
Datenzugriffe sind zwar nicht nominell für jeden Befehl notwendig, aber bei BURST-Zyklen stellt
sich auch auf dem Datenpfad ein vergleichbar hoher Durchsatz ein. Die Speicherbaustein für den
Daten-Cache können also nicht wesentlich langsamer sein.
3.3
Programm-abhängige Leistungsmodelle
3.3.1 Einflußgrößen
Die Leistung eines Prozessors kann man auch über die Ausführungszeit irgendwelcher Standardprogramme bestimmen:
9
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Tprog := Iprog * Cprog * T
Dabei sind:
− Tprog: die Programmausführungszeit
− Iprog: die Zahl der dynamisch vom Programm ausgeführten Befehle
− CPIprog: Zahl der Maschinenzyklen, die der Prozessor durchschnittlich für einen Befehl des
Programms benötigt.
Das Programm kann hier ein Systemprogramm oder ein Anwendungsprogramm sein, auch ein MultiTasking-fähiges Programmsystem.
Zu beachten ist dabei, daß Iprog nicht nur die Zahl der sich aus dem Anwenderprogramm
ergebenden Befehle darstellt, sondern darüber hinaus viele weitere Befehle aus eingebundenen
Systemroutinen beinhalten kann.
CPIprog ist notwendigerweise programmabhängig, wie bereits früher diskutiert.
Ein hoher Anteil an Gleitkommabefehlen (wie in SPICE) schraubt den Zahlenwert auf weit über 1,
während eine Beschränkung auf Integeroperationen bei RISC-Prozessoren zu Werten nahe bei 1
führen kann.
Man kann nun in der obigen Formel zu einer minimalen Ausführungszeit kommen, wenn man jeden
Faktor für sich minimiert. Schön wäre das, funktioniert aber nicht, weil die einzelnen Faktoren nicht
voneinander unabhängig sein. Deshalb müssen wir uns die Faktoren einzeln ansehen.
3.3.2 Die Zahl der ausgeführten Befehle
Die "alten" CISC-Prozessoren hatten für nahezu jede Anwendung eine Sammlung von Spezialbefehlen, die möglichst gut auf die Hochsprachen (wie z. B. FORTRAN) angepaßt waren. Compiler
hatten es einfach.
Seit der Einführung von RISC hat ein Compiler in der Regel mehr zu tun und muß häufig für einen
komplexen Befehl (oder CISC-Befehl) eine Folge von RISC-Befehlen ein setzen. Deshalb sind
RISC-Maschinenprogramme typischerweise länger als solche für CISC-Maschinen. Als Daumenregel
ist annehmbar, daß C-Programe für RISC-Maschinen etwa 20% mehr Maschinenbefehle also solche
für CISC-Rechner enthalten.
Bei manchen Rechnern, die aus CISC-Architekturen entstanden sind (z. B. Pentium), wird versucht,
mittels komplexer Hardware auch aufwendige Operationen in einem Taktzyklus ablaufen zu lassen
(z. B. durch Festkommamultiplikation).
Wenn man aber deshalb wiederum die Taktzeit verändern muß, kann damit, über alle Befehle eines
Programms gemittelt gesehen, genau der entgegengesetzte Effekt auftreten. Ein auch für RISC
gangbarer Ausweg ist die Minimierung der zur Zwischenspeicherung von Variablen notwendigen
Speicherzugriffe. Ein RISC-tauglicher Compiler wird deshalb versuchen, alle Variablen möglichst
lange in Registern aufzubewahren. Einen wesentlichen Einfluß hat auch der Aufwand, den das
Betriebssystem zusätzlich benötigt.
Mittels einer optimalen Abstimmung zwischen Compiler und Hardware kann man zu guten
Ergebnissen kommen. Die Tendenz ist aber eher, im komplexen Prozessoren wie dem Pentium
Compileraufgaben durch spezielle Hardware ausführen zu lassen, z. B. sogar das Umordnen von
Befehlen zur Vermeidung von Pipeline-Hazards. (Der große Vorteil ist dann die weitgehende
Entkopplung des Compilers von der Prozessorstruktur).
3.3.3 Zyklen pro Programmbefehl: CPIprog
10
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Die Leistung eines Prozessors kann man natürlich einfach dadurch anheben, daß man die Taktrate
der System-Clock anhebt. Dieses Mittel wirkt auch nur dann, wenn nicht gleichzeitig die Anzahl der
für die Abarbeitung eines einzigen Befehls notwendigen Taktzyklen steigt. Anders herum kann die
Leistung von zwei Rechnern mit derselben Taktrate aber sehr unterschiedlich sein, je nachdem, wie
viele Taktzyklen der Rechner für die Ausführung eines einzigen Befehls benötigt.
RISC-Prozessoren waren vor allem im Anfang deshalb schneller als die CISC-Konkurrenz, weil man
mit im Mittel 1,2 bis 1,5 Taktzyklen pro Befehl gegenüber 4,5 bis 10 auskam. Heutige CISCProzessoren (z. B. Intel Pentium) sind auch deshalb recht schnell, weil sie im Mittel ebenfalls mit
etwa 2 Takten pro Befehl auskommen.
Es ist tatsächlich möglich, den CPI-Wert auf etwa 1 zu senken. Die Maßnahmen auf der Seite der
Rechnerarchitektur dazu sind:
− Speicherzugriff in einem Takt durch schnelle Zwischenspeicher (Cache)
− parallel-versetzte Abarbeitung mehrerer Befehle durch (Phasen-) Pipelining.
Will man den CPI-Wert auf unter 1 senken, so muß der Prozessor eine superskalare Architektur
haben, also tatsächlich mehr als einen Befehl völlig parallel verarbeiten.
Pipeline- Prozessoren kann man natürlich für RISC- oder für CISC-Befehlssätze bauen. Für RISC ist
aber wegen der einfacheren Befehle typischerweise die Pipeline kürzer, hat also weniger Stufen, und
ist in der Regel besser und einfacher zu füllen. Man hat weniger "Stalls", wo die Pipeline zur
Vermeidung von Konflikten mit Nulloperationen (NOPs) gefüttert werden muß.
3.3.4 Taktzykluszeit T
Die Taktzykluszeit T ist ein wichtiger, aber vielleicht nicht der wichtigste Parameter. Er ist aber wie
kein anderer direkt von der Halbleitertechnologie abhängig. Die Taktrate ist wiederum direkt
abhängig von der Grenzfrequenz (der maximal zulässigen Taktrate) für einzelne Gatter und
Transistoren einerseits und der Verzögerungszeit von Gattern und Transistoren andererseits. Und
hier wird der Einfluß der Großintegration voll spürbar.
Die maximale Schaltfrequenz eines MOS-Transistors steigt umgekehrt proportional mit seiner
Kanallänge. Wenn man die Ausdehnung eines Gatters um den Faktor 2 verringert, so verkürzen sich
die Verbindungsleitungen um denselben Faktor, im Prinzip also auch die Laufzeiten zwischen den
Bau-teilen.
Gleichzeitig kann man um den Faktor 4 höher integrieren.
Dieses Gesetz ist direkt ablesbar:
Die ersten Mikroprozessoren hatten Taktraten von ca. 1-5 MHz und Strukturgrößen (z. B.
Kanallängen) von etwa 5-10 Mikrometern. Ein Pentium wurde bei Strukturgrößen von ca. 0,8 bis
0,35 Mikrometern und Taktraten zwischen 50 und 200 MHz gefertigt. Der Pentium II wird wohl mit
bald mit 300 MHz bei 0,25 Mikrometern Strukturgröße betreibbar sein.
(Es gibt aber einen Nachteil: Eine vierfach höhere Dichte pro Flächeneinheit bedeutet bei gleicher
Spannung und gleichen Strömen pro Bauelement eine vierfach höhere Verlustleistung. Die steigt
aber auch noch mal proportional der Taktrate. Selbst wenn man Spannungen und Ströme teilweise
mit herunterskaliert gibt es immer noch eine erhebliche Steigerung der Verlustleistung).
Wegen der einfacheren Befehlsentschlüsselung kann man bei RISC-Maschinen im Mittel auf höhere
Taktraten bei sonst gleicher Technologie gehen. Deshalb ist bei RISC-Maschinen die Zugriffszeit auf
den Befehlsspeicher (meistens ein Cache) der wirkliche Engpaß. Wir erinnern uns: Beim
11
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
gepipelineten Prozessor muß für jeden neuen Taktzyklus jeweils ein Befehl geholt, gelesen und
entschlüsselt werden.
3.4
Beschleunigung und Effizienz bei Parallelrechnern
Wen die Leistung eines einzelnen Prozessors an Grenzen stößt, ist es naheliegend, mehrere parallel
arbeitende Prozessoren oder Rechenwerke zu verwenden. Ein erster Schritt ist das Phasenpipelining,
bei dem zunächst die Teile eines einzelnen Rechners dauernd parallel tätig sind. Geht man darüber
hinaus zu superskalaren Rechnern über, so sind dann auch komplette Funktionseinheiten (z. B. das
Rechenwerk, also ALU, Multiplizierer, Dividierer, Shifter) mehrfach vorhanden. In einer weiteren
Stufe der Parallelisierung schaltet man komplette Prozessoren parallel.
Der "Speed-Up" wird als Maß für die Beschleunigung bei Multiprozessoren gegenüber einem
Einzelprozessor definiert und meistens bei MIMD-Rechnern oder auch bei SIMD-Rechnern
verwendet. Mittels der Messung eines Speed-Ups kann man feststellen, ob und welchen
Geschwindigkeitsvorteil die Parallelisierung bezüglich eines bestimmten Programms ergeben hat.
Dazu ist es aber notwendig, in beiden Fällen algorithmisch gleiche Programme zu verwenden.
Tatsächlich wird man im Hinblick auf die Parallelisierung oft andere Algorithmen verwenden.
Die Formel für den Speed-Up kann man angeben zu: Sn := T1 / Tn
Sn ist der Speed-Up bei n parallelen Prozessoren und Rechenwerken,
T1 ist die Ausführungszeit der seriellen Programme,
Tn ist die Ausführungszeit der parallelen Version auf n Rechenwerken oder n Prozessoren.
Das ist jetzt keine höhere Mathematik. In der Praxis wird man fast immer finden, daß Sn > n ist. Dies
ist dadurch begründet, daß einmal ein Programmcode nicht unbegrenzt Parallelität "enthält",
andererseits die Organisation paralleler Abläufe aber auch zusätzlich Zeit kostet.
Es kommt zwar selten, aber durchaus vor, daß die algorithmischen Verbesserungen, die an einem
Programm zur "Parallelisierung" durchgeführt wurden, sich dann tatsächlich in einem super-linearen
Leistungsgewinn äußern. Zunächst werden solche "Kandidaten" aber erst mal als Mogelpackung
verdächtigt.
Für Parallelrechner kann man auch eine Effizient angeben, die bezeichnet wird mit: En = Sn / n
Im allgemeinen gilt En <= 1.
Bei Programmen "allgemeiner" Art (ablaufend auf einfachen Prozessoren) ist es typisch, daß bis n =
2 oder n = 3 der Gewinn noch recht gut ist, darüber hinaus aber stark abfällt.
3.5
Benchmark-Programme
Zur Evaluierung von Rechnern und deren Leistung für einen bestimmten Anwendungsbereich werden
seit langem Benchmarks verwendet, also "typische" Programme. Es gibt sowohl "synthetische"
Benchmarks als auch reale Programme, die als typische Benchmarks verwendet werden. Reale
Programme sind z. B. Text für die Textverarbeitung, der GNU GCC-Compiler und der elektrische
Simulator SPICE. Gemeinsam ist allen bekannten Benchmarks, daß sie auf frei programmierbare
Rechner und einen kontinuierlichen Programmablauf ausgerichtet sind. Sie taugen deshalb kaum für
die Abschätzung von Rechnern und Prozessoren bei Interrupt-getriebenen Anwendungen.
Nachfolgend sollen einige synthetische Benchmarks vorgestellt werden.
Der Whetstone-Benchmark wurde 1976 von Curnow und Wichman als Algol-60 Programm
entwickelt.
12
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Es enthält Teile von vielen technisch-wissenschaftlichen ALGOL-Programmen. Später folgte eine
FORTRAN-Version, die heute ausschließlich verwendet wird. Die Leistung eines Rechners wird
dann in KWIPS oder MWIPS angegeben, also Kilo- oder Mega-Wheatstone-Befehlen pro Sekunde.
Da diese Programm aus vielen kleinen, "lokal" reagierenden Teilen mit auch nur lokalen Schleifen
besteht, läuft es bei mit Pipeline und Cache ausgerüsteten Rechnern typischerweise zu gut ab, verhält
sich also relativ zu günstig.
Der Dhrystone-Benchmark wurde 1984 / 1990 von Weicker zunächst in ADA vorgestellt, heute
werden fast ausschließlich Versionen in C verwendet. Dieser Benchmark stützt sich vorwiegend auf
statistische Auswertungen aus der Systemprogrammierung.
Dieser Benchmark enthält nur etwa 100 Anweisungen und ist zusammengestellt auf der Basis
"tatsächlich" vorkommender Datentypen. Auch die Lokalitätseigenschaften von Variablen,
Parametern und Konstanten sind auf reale Systemprogramme abgestimmt. Wegen der geringen
Codegröße neigt auch dieser Benchmark dazu, die Leistung von Caches zu gut wiederzugeben.
Der LINPACK-Benchmark ist ein 1976 entwickeltes FORTRAN-Programm zur Lösung eines
linearen Gleichungssystems mit 100 Gleichungen für 100 Unbekannte auf der Basis der GaussElimination. Es kommen viele Gleitkommaoperationen vor, die allerdings vorwiegend in Unterprogrammen, den Basic Linear Algebra Subprograms (also einer Art mathematischer Programmbibliothek) ausgeführt werden. Diese können in FORTRAN oder in Assembler programmiert sein.
Wenn man nun die Laufzeiten der Subroutinen in Assembler kennt, so sind rückwärts wieder
Schlüsse auf die Qualität des FORTRAN-Compilers möglich.
LINPACK ist der De-Fakto-Standard für Supercomputer mit Vektor-Architektur. Da aber moderne
Workstations mit RISC-Prozessoren und sogar PCs mit High-End-Mikroprozessoren zunehmend
Architekturmerkmale aufweisen, die früher Superrechnern vorbehalten waren, wird dieser
Benchmark zunehmend Allgemeingut. Allerdings werden auch LINPACK-Benchmarks für
Gleichungssysteme unterschiedlicher Größenordnung verwendet, also auch z. B. 1000 * 1000
Matrizen verwendet.
In Berechnungen der in LINPACK verwendeten Art kommen immer wieder Programmzeilen der
Form: y[i] = y [i] + a * x [i] vor.
Rechner, die einen solchen Befehl in einem Makrobefehl ohne explizite Zwischenspeicherung der
Variablen durchführen können, sind eindeutig im Vorteil. Operationen dieser Art sind auch für die
Berechnung und Darstellung von Bildinformation wichtig. Der IBM Power PC hatte diesen Befehl
auch. Die Intel-Prozessoren wurden in der MMX-Version damit nachgerüstet.
Die Brauchbarkeit des LINPACK-Benchmarks ist deshalb beschränkt, weil komplexere mathematische Funktionen nicht vorkommen, z. B. keine Winkelfunktionen.
Große Vektor-Maschinen wie z. B. die Cray Y-MP erreichen bei Matrizen mit n = 10 000 und mehr
Knoten LINPACK-Werte von 10 - 20 GFlops (mit z. B. bei Cray Y-MP 16 Prozessoren), aber beim
LINPACK mit n = 100 nur um die 500 MFLOPs, wobei dann eine CRAY Y-MP mit 16 Prozessoren
nicht mal doppelt so schnell ist wie die mit einem Prozessor.
Im Jahre 1988 gründeten SUN, MIPS, HP und Apollo eine Initiative für den SPEC-Mark-Standard,
der sich nachträglich mehr als 20 Unternehmen angeschlossen haben.
Bis dahin war es nämlich fast üblich, bei mittleren Rechnern unterhalb der Mainframes und CRAYS
in Ermangelung anderer Standards einfach die Leistung der VAX 11 / 780 (die bei etwa einem MIPs
lag) als Standard zu nehmen. In diesem Fall wurde eine Basis von mehreren Programmen als
"Testsuite" zugrundegelegt, die aus möglichst unterschiedlichen Anwendungs-bereichen stammen
sollten.
13
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Die erste Version (SPEC89 mit SPECfp89 und SPECint89) enthielt insgesamt 10 FORTRAN und
C-Programme mit 150 000 Zeilen Code, die Suite SPEC92 mit SPECint92 und SPECfp92) enthält
11 weitere Programme.
Um einen Rechner zu charakterisieren, wird für jedes der Benchmark-Programme die
Ausführungszeit als Vielfaches der Laufzeit der VAX 11 / 780 (mit dem Betriebssystem VMS)
angegeben. Die VAX 11/780 wird heute als der typische 1-MIPS-Rechner angesehen.
Wie weit heutige Prozessoren die VAX von 1978 übertreffen, zeigt die nachfolgende Tabelle:
Rechner
SPECmark89
IBM POWER2
Model 990
71,5 MHz
DEC Alpha
Model 610
200 MHz
SPECint92
SPECfp92
120
250
106,5
200,4
MIPS R 4400
SNI RM 600
75 MHz
95
98
HP PA-7100
99 MHz
81
150
Intel Pentium
SNI PCE-5S
66 MHz
TI Super Sparc
Sun SS-10 / 41
40 MHz
MIPS R4000
50 MHz
62,5
67
62
52,6
64,7
58,3
61,5
Abb. 3.6: SPECmark-Tabelle für verschiedene Prozessoren, nominiert auf die Leistung einer
VAX 11 / 780 von 1978
Ein 100 - MHz-Pentium dürfte also die Leistung der guten alten VAX um den Faktor 100
übertreffen.
Nur implizit taucht hier das Problem auf, daß die Leistung eines Prozessors für ein bestimmtes
Programm natürlich auch vom Compiler abhängig ist. Bei den SPEC-Marks wurde vermieden,
Programme aufzunehmen, die in ihrer Ausführungszeit sehr stark von den optimierenden
Eigenschaften eines Compilers abhängig sind.
3.6
Leistungsbewertung und Schätzverfahren
Beim betrieb eines großen Rechnersystems waren und sind Werkzeuge notwendig, welche das
Verhalten und die Auslastung wiedergeben. Solche "Monitore" werden aber heute vorwiegend für
Computernetze eingesetzt, z. B. von einem gewissen Herrn Pawell an der BTU Cottbus.
Als ein viel ernsterer Engpaß hat sich die Leistungsbewertung in der Entwurfsphase von Rechnern
und, dort noch viel häufiger, bei eingebetteten Systemen herausgestellt.
14
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Bus
SensorSignale
Prozessor
AktuatorSignale
Speicher
Sensoren
Stellglieder
Logik
I / O - Baugruppen ( D / A )
Bus
Abb. 3.7: Eingebettetes Rechnersystem
Eingebettete rechnerbasierte Systeme haben im Vergleich zu "Allerweltsrechnern" wie PCs einige
dezidiert andere Eigenschaften. Unter anderem gehört dazu, daß man den für die Anwendung
optimalen Prozessor oder, noch weitgehender, die jeweils optimale Konfiguration aus Hardware und
Software wählt.
Die Aufgabe besteht also darin, zunächst abzuschätzen welcher Prozessor (mit seinem Compiler) für
die jeweilige Aufgabe geeignet sein könnte und dann nachzuweisen, daß der Prozessor mit den
gegebenen Leistungsdaten tatsächlich für alle Datensätze am Eingang (und z. B. alle möglichen
Interruptbedingungen) diese Aufgaben erfüllt.
Für den Entwerfer eines Allzweckrechners ist das eine ganz und gar ungewohnte Problematik. Er
kennt allerdings einige Werkzeuge des Kollegen vom Hardwareentwurf. Und dieser hat z. B. einen
Simulator, mit dem er nicht nur Gatter, sondern sogar funktionale Blöcke auf der Basis von Struktur
und / oder Verhalten simulieren kann. Das sind die sogenannten Registertransfer-simulatoren, die z.
B. auf der Basis von VHDL oder VERILOG arbeiten.
Eingangsdaten
Compiled
Code
ProzessorModell
VHDL-Simulator
SpeicherModell
Digitale
Signale
Abb. 3.8: HW / SW Co-Simulation mittels RT-Level-Simulator
Gehen wir zunächst davon aus, daß die Eignung eines Standardprozessors für die gestellte Aufgabe
validierte werden soll. Dann ist dazu (gegen meistens viel Geld) vom Hersteller des Prozessors eine
Verhaltensmodell verfügbar. Strukturmodelle gibt es auch manchmal, aber die sind selbst für sehr
einfache Mikroprozessoren astronomisch teuer. Wenn der Speicher nur ein RAM oder ROM ist,
genügt ein einfaches Speichermodell (in VHDL), das man zur Not selbst schreiben kann. Ist der
Speicher aber ein Cache-basiertes Speichersystem. so führt kein Weg an einer Kopplung mit einem
speziellen Cache-Simulator vorbei. Der Code wird als Binärcode sozusagen Clock-synchron fiktiv
aus dem Speicher zugefüttert.
15
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Jetzt kann man sich wirklich wie bei der Logiksimulation auf jeder zugreifbaren Leitung, also z. B.
an den Ein- und Ausgängen des Prozessors, die digitalen Signale anschauen. Manche Simulatoren
besitzen sogar ein spezielles C-Interface.
Bei aller Präzision ist diese Methode sehr langsam, Simulationszeiten von Wochen sind durchaus
angebracht.
Deshalb eignet sich die HW/SW Co-Simulation auch nicht für die Exploration unterschiedlicher
Entwurfsalternativen.
Code
Schätzwerkzeug
ProzessorModell
- Befehlssatz
Compiler
- CPI
- Taktrate
Speicher
Modell
Laufzeiten
Abb. 3.9: Schätzverfahren für die Ablaufzeit von Code auf vorgegebenen Prozessorstrukturen
Alternativ dazu werden z. Zt. Schätzverfahren entwickelt. Diese sollen es gestatten, auf der Basis
von einfachen Prozessorbeschreibungen die Laufzeiten vorgegebenen Codes abzuschätzen. Sie
müssen dazu im Vergleich zur Co-Simulation um ca. den Faktor 1000 schneller sein. Auf der
anderen Seite ist eine Unsicherheit von +/- 30% für die Abschätzung zu ertragen, da weder das
Cache-Verhalten noch Pipelinestrukturen auf diese Weise exakt behandelbar sind.
Eingangsdaten
Instruction
Set
Simulator
(Proz.- spez.)
Code
(Assembler)
Register- /
SpeicherBelegungen
Abb. 3.10: Instruction Set Simulator
Trotzdem reichen solche Verfahren für die Exploration von möglichen Entwurfsalternativen sehr
wertvoll.
Wenn ein bestimmter (kommerzieller) Prozessor ausgewählt ist, so gibt es noch eine weitere
Alternative.
Speziell für einzelne Prozessoren (z. B. 8086, 8051) sind sogenannte Instruction-Set-Simulatoren
verfügbar. Sie simulieren das Verhalten des Prozessors auf der Basis von Taktzyklen und erlauben
z. B., sich nach jedem Takt den Inhalt der Register und der Eingangs-/Ausgangslei-tungen
anzusehen.
Sie sind ca. um den Faktor 10-100 langsamer als die Schätzverfahren, aber auch wesentlich genauer.
Es gibt heute auch Arbeiten zur Kopplung solcher Simulatoren auf verschiedenen Ebenen.
16
BTU Cottbus, Prozessor-Architektur, Kapitel 3, WS 99/00
Natürlich sind die Verhältnisse am günstigsten, wenn für eine Anwendung der geeignete Prozessor
im Entwicklungssystem selbst verfügbar ist. Der Pentium im PC wird eher selten als "embedded"
Prozessor verwendet werden. Aber es gibt durchaus kostengünstige PC-basierte Entwicklungsumgebungen für Low-Cost-Prozessoren, bei denen man ein Board an die Drucker-schnittstelle
anklemmen kann, auf dem sich der Zielprozessor befindet. Und dann ist es möglich, ein entwickeltes
und übersetztes Programm in dessen lokalen Speicher zu kopieren, und über den PC den Ablauf zu
stoppen.
Die praktischen Probleme allein schon bei der Messung von Codeablaufzeiten auf Prozessoren sind
ganz erheblich. Zunächst laufen ja fast alle Programme auf größeren Rechnern in einer Betriessystemumgebung ab.
Deshalb unterscheidet man für die Ablaufzeit auch eine "CPU-Zeit" und eine "elapsed Zeit", welche
Wartezeiten und Aufwendungen des Betriebssystems einschließt. Die Messung der reinen CPU-Zeit
erfordert die Verfügbarkeit entsprechender Software, welche nicht standardmäßig "mitgeliefert"
wird.
Und auch dann können sich noch seltsame Effekte ergeben.
Die Frage der Verfügbarkeit von Daten und Befehlen im Cache wurde schon diskutiert.
Eine weitere Frage ist, ob ein Speicherzugriff im "Burst"-Modus gelingt oder nicht.
In einer früheren Vorlesung wurde auch das Problem des ausgerichteten bzw. nicht ausgerichteten
Speicherzugriffs erwähnt:
Die Speicheradressierung erfolgt Byteweise, also mit 8 Bit pro Adresse. Für einen 32-Bit-Wort
müssen also 4 Bytes übertragen werden. Es ist nun sicherlich wünschenswert, daß die benötigten 4
Bytes auch in der richtigen Reihenfolge hintereinander im Speicher (bzw. im Cache) stehen. Das muß
aber nicht sein. Dann müssen die Bytes erst "ausgerichtet" werden, was mindestens doppelt so lange
dauert wie ein normaler Zugriff. In einem Experiment verhielt sich dasselbe Programm mit denselben
Daten völlig irregulär in der Weise, daß die Ablaufzeit zwischen einem einfachen und dem doppelten
Wert abwechselte.
17
Document
Kategorie
Technik
Seitenansichten
59
Dateigröße
67 KB
Tags
1/--Seiten
melden