Die Prozessor-Radarkontrolle

center

** Die Zeiten, in denen es bei jedem Programm klar war, mit wieviel Megahertz der zugrundeliegende Prozessor im ATARI lief, sind lange schon vorbei. Wir geben Tips zur Prozessor-Taktmessung am Falcon.**

Gerade diese Information ist aber für viele Programme sehr nützlich, die sich mit zeitkritischen Aufgaben befassen oder einfach nur über die Leistungsfähigkeit des jeweiligen Prozessors informieren möchten. Das hier beschriebene Verfahren ermöglicht die softwaremäßige "exakte" Bestimmung der Frequenz eines MC68030 (oder höher), unabhängig davon, in welcher Systemumgebung (Busbreite oder -takt) sich die CPU befindet.

Nach Einführung des TT und vor allem des Falcon 030 war es nur eine Frage der Zeit, bis findige Bastler sich daran machten, auch für diese Rechner Prozessorbeschleuniger zu entwickeln, die wie im Beispiel Falcon die CPU von standardmäßig 16 MHz auf bis zu 40 MHz Takt katapultieren [1]. Spätestens seit diesem Zeitpunkt sollte man sich nicht mehr nur auf die Informationen aus dem Cookiejar verlassen, dessen Einträge zwar verraten, welcher Rechner und welche CPU vorhanden sind, aber keinesfalls Rückschlüsse auf den aktuellen CPU-Takt zulassen. Angenommen, man will die Detailstufe der Grafik eines Spiels abhängig von der Rechenleistung der CPU machen oder die Qualität bei der Echtzeitbearbeitung von Soundsamples mit steigender Rechenpower immer besser werden lassen, so ist man auf eine andere Methode angewiesen.

Tempus fugit

Die prinzipielle Idee ist ganz einfach. Man lässt den Prozessor eine bestimmte Befehlsfolge abarbeiten und misst mit einem internen Zähler die Zeit, die er dafür gebraucht hat. Hat man nun einen Bezugswert, zu dem man die gemessene Zeit in Relation setzen kann, lässt sich der aktuelle CPU-Takt durch eine leichte Rechnung schnell ermitteln. Doch wie misst man die verstrichene Zeit, wenn das System doch verschieden schnell sein kann?

Dafür gibt es glücklicherweise eine systemunabhängige Lösung. Jeder Rechner der ST-Serie besitzt einen Baustein (MFP), der vier unabhängige Timer beinhaltet. Der MFP wird von einem eigenen Oszillator gesteuert, dessen Frequenz bei allen Modellen konstant 2,4576 MHz beträgt. Der erste Timer (A) wird vom Betriebssystem nicht verwendet und kann daher für unsere Zwecke benutzt werden.

Um möglichst exakte Zeitmessungen durchzuführen, sollte der kleinste Verteiler (1/4) für diesen Timer gewählt werden. Es ist somit möglich, Zeiten in 1.6276s Intervallen zu messen, was wohl für die momentan gängigen Prozessorfrequenzen ausreichen sollte.

Der Timer besitzt weiterhin ein bytegroßes Datenregister, dessen Inhalt um 1 dekrementiert wird, sobald dieses Zeitintervall verstrichen ist. Somit liegen die Messungen im Bereich von 1.6276s bis 415.038s. Um nun die Zeitdauer einer Befehlsfolge des Prozessors zu messen, muss also nur das TimerDatenregister mit 255 initialisiert und der Timer gestartet werden. Nach dem Durchlaufen der Befehlsfolge wird der Timer wieder gestoppt und das Datenregister ausgelesen.

Dummy-Schleife

Da das Zeitmessen nun kein Problem mehr ist, stellt sich jetzt die Frage, was denn überhaupt gemessen werden soll.

Es bietet sich natürlich an, eine Schleife zu testen, da man hier die Anzahl der zu durchlaufenden Befehle bequem variieren kann. Weiterhin sollte jeder Durchlauf zu absolut identischem Abarbeiten der Befehle führen, damit der Prozessor immer die gleiche Zeit dafür benötigt.

Im vorliegenden Programm wird in der Schleife ein Divisionsbefehl abgearbeitet, da dieser nicht intern optimiert werden kann, bedingt durch das iterative Vorgehen des Prozessors. Als Parameter dienen eine Konstante und ein Datenregister, dessen Inhalt mit 0 initialisiert und durch die Division natürlich nicht verändert wird.

Cache is King

Ein weiteres Problem stellen die Zugriffe des Prozessors über den Bus auf das RAM dar. Verschie
dene Bustakte und Busbreiten gepaart mit Performance-Schwankungen durch die Mitbenutzung anderer Systemkomponenten (besonders der Videohardware) führen zu extremen Differenzen in der übertragungsgeschwindigkeit der Befehle aus dem RAM in den Prozessor. Dieser Effekt würde eine präzise Messung des CPU-Takts fast unmöglich machen und nur durch einen viel komplizierteren Algorithmus zu bezwingen sein.

Glücklicherweise besitzen aber die Prozessoren der 68000er-Reihe ab dem 68030 einen integrierten Speicher (Cache) für Daten und Befehle, der in der Lage ist, die komplette Testschleife im Prozessor zu halten und somit die Buszugriffe überflüssig macht. Da die Befehle aber erst einmal in den Cache gelangen müssen, was übrigens durch Ausführen derselben geschieht, wird die Testschleife einmal unverbindlich durchlaufen, bevor es ernst wird und es auf die Zeit ankommt.

Der letzte Störfaktor, den man noch aus dem Weg räumen muss, sind die unangenehmen Unterbrechungen des Programms durch Interrupts, wie z.B. der VBI, der bei jedem Bildaufbau einmal aufgerufen wird. Dies verhindert man durch Ausmaskieren aller möglichen Interruptquellen im CPU-Statusregister für den entsprechenden Zeitraum. Jetzt kann man sicher sein, dass der Prozessor sich mit voller Geschwindigkeit und ungeteilter Aufmerksamkeit der Schleife widmet und die gemessene Zeit die wirklichen Verhältnisse widerspiegelt.

Aus Zeit mach Takt

Der Wert aus dem Timerdatenregister stellt für sich allein keine aussagekräftige Größe dar. Erst der Vergleich mit dem Wert aus einer Messung mit bekanntem CPU-Takt führt zu der einfachen Formel:
Takt= (Bezugszeit*Bezugstakt)/Messzeit

Wie man sieht, ist das Verhältnis von Zeit zu Takt antiproportional mit dem konstanten Faktor (Bezugszeit*Bezugstakt). Aus der Formel lässt sich auch deutlich erkennen, dass je höher der CPU-Takt wird, sich die gemessenen Zeiten immer geringer voneinander unterscheiden und ab einer bestimmten Taktobergrenze nicht mehr unterscheidbar sind bzw. zu einem Fehler wegen Division durch 0 führen. Genauso wird bei kleiner werdendem Takt die Messzeit immer länger und führt entsprechend zu einem überlauf des bytegroßen Timerdatenregister, was zwar nicht zu einem Absturz, aber zu völlig falschen Werten führen würde. Aus einem sehr langsamen würde daher ein pfeilschneller Prozessor, weil nach einem überlauf die Messzeit nahe der Null liegt. Im vorliegenden Programm wurden die Werte so gewählt, dass ein 68030 im Bereich von 8 MHz bis 50 Mhz in 1 Mhz-Schritten gemessen werden kann. Wenn ein viel kleinerer Bereich abgedeckt werden soll, kann man auch höhere oder tiefere Frequenzen messen und dies natürlich noch etwas genauer.

Das Anpassen der Routine erfolgt in 2 Schritten:

  1. verringern (für kleinere Frequenzen) oder erhöhen (für größere Frequenzen) der Anzahl der Schleifendurchläufe.
  2. neuen Bezugswert bei bekannter Frequenz messen und eintragen.
    Auch das Anpassen an andere Prozessoren der Reihe funktioniert genauso. Für ein universell einsetzbares Programm sollte man sich die Bezugswerte in einer Tabelle speichern und anhand des Eintrags in der Cookiejar die Werte entsprechend des Prozessors wählen.

Für den 68000er ist das Programm natürlich nicht lauffähig, kann aber durch Weglassen der Cache-Manipulationsbefehle angepaßt werden. Hier würde jedoch wiederum der Bus mitgemessen werden, was man aber verschmerzen kann, da bisher alle STs, die einen 68000er innehaben, den gleichen 8 Mhz Bus besitzen und das Videosubsystem den Bus immer gleich belastet aufgrund des fixen 32 KB Bildschirmspeichers.

Aufrufkonvention Aus Assembler- oder C-Programmen kann die Routine wie gewohnt aufgerufen werden. Alle Register bis auf d0 werden gerettet. Beim Rücksprung wird in d0 der aktuelle Takt als Integer zurückgegeben.

Literaturangabe:
[1] Hardwaretest: Speed Resolution Card, ATARI-Inside Sonderheft 1/95
[2] Jankowski, Rabich, Rescke, ATARI ST-STE-TT Profibuch, erschien 1991 im Sybex Verlag, ISBN 3-88745-8885


Natalie Lübke
Aus: Atari Inside 04 / 1996, Seite 43

Links

Copyright-Bestimmungen: siehe Über diese Seite