Seit es neben Prozessoren von Intel auch Pentium-kompatible Prozessoren anderer Hersteller auf dem Markt gibt, wimmelt es in den Fachzeitschriften von Vergleichen und Ratschlägen, welcher der Schnellere ist. Diese Seite beschreibt, worin diese Unterschiede begründet sind.
Bis zum 486 war die Sache bei PC-CPUs einfach: Alle Prozessoren waren mehr oder weniger eine Kopie oder Abwandelung des original Intel-Chipdesigns. Aber seitdem mußten die anderen Hersteller ihre Prozessoren komplett selber entwerfen, wodurch ihr Aufbau teilweise erheblich vom Original abweicht. Dabei weist jedes Design in den verschiedensten Bereichen Stärken und Schwächen auf.
Am besten verkaufen sich CPUs, die im Durchschnitt am schnellsten sind, sprich die bei Durchschnittsanwendungen am besten sind. Und diese werden meistens in C geschrieben. Das entstehende Programm enthält meist nur relativ wenige Befehle und Kniffe, welche zudem relativ stark vermischt sind. Deshalb werden die Prozessoren auf diese Art von Programmcode optimiert. Hierbei liegen die Prozessoren recht nahe beeinander.
Ich hatte die Möglichkeit, einen 100MHz Pentium, einen Cyrix 166+ und einen AMD K6-333 in ein und demselben System mit ein und demselben Mainboard mit meinen eigenen Programmen zu testen.
Auffallend war, daß bei normalen Anwendungen (Textverarbeitung, Dateimanager, einfachere Grafikprogramme, Webbrowser) der fühlbare Unterschied selbst zwischen dem P100 und dem K6-333 auffallend gering war. Hier machen sich die Geschwindigkeit von Grafikkarte, Festplatte, CDROM, Speicher (sowie dessen Größe), Hauptplatine und Betriebssytem sowie vor allem deren Zusammenspiel weitaus stärker bemerkbar.
Hier schrieb ich einen Grafikeffekt, der die Daten eines 64KB großen Speicherblocks in einzelnen hintereinanderliegenden Bytes einliest und miteinander verrechnet. Eine Situation, die auch in Grafikverarbeitungen und Suchalgorithmen vorkommen kann.
Hier kam der Cyrix166 fast an den K6 heran, der P100 lag weit abgeschlagen hinten. Der Grund ist einfach: Der Cyrix kann einzelne Byte(8Bit)-Zugriffe zu einem DWord(32Bit)-Zugriff bündeln, der Pentium nicht. Dadurch sind diese Zugriffe fast 4mal so schnell als auf dem Pentium, was sich auch auf das gesamte Programm auswirkt, da dieses zu 2/3 aus diesen Zugriffen besteht.
Interessant war auch, daß das Programm auf dem K6 ab ca. 266 MHz kaum schneller wurde. Hier kam wohl der Grafikspeicher nicht mehr mit der Datenmenge mit. P.S.: Der Pentium II kann die Bytezugriffe ebenfalls zusammenpacken. Leider konnte ich dies nicht testen.
Nun wurden die CPUs mit einem Programm getestet, das größtenteils aus etwas komplexeren mathematischen Berechnungen bestand. Dies tritt vor allem bei Fraktalen und Raytracern auf. Die erste, unoptimierte Version lief auf dem Cyrix166 nur unwesentlich schneller als auf dem P100. Der K6-333 war etwa doppelt so schnell. Schon hier zeigte sich das der Pentium das bessere FPU-Layout hat.
Nun wurde der Code auf den Pentium hin optimiert: Bekannt ist, daß nur eine FPU-Instruktion gleichzeitig ausgeführt werden kann. Was jedoch nicht so verbreitet ist, ist daß der Pentium aber voneinander unabhängige FPU-Berechnungen danach gleichzeitig berechnen kann, da die Berechnung selbst länger dauert als das Starten der Berechnung durch den FPU-Befehl.
Solange der eine Befehl noch rechnet, kann man schon andere starten, anstatt auf das Ergebnis des Ersten zu warten. Jedoch greifen die x86-FPU-Befehle immer auf das ST(0)-Register zu. Da auf dem Pentium aber die Register ihre Namen tauschen können, greifen unter Umständen zwei Befehle auf ein Register namens ST(0) zu, welche aber in Wirklichkeit verschieden sind!
Um die Namen zu vertauschen benützt man den Befehl FXCH, der zwei Register miteinander vertauscht. In Wirklichkeit werden die Register nur umbenannt, ein zeitaufwendiges Vertauschen ihrer Inhalte findet nicht statt!
Dies wissend optimierte ich den Programmcode. Das Ergebnis war: Der P100 kam fast an den 3 mal so schnellen K6 heran, während die anderen CPUs gleich schnell wie vorher blieben (theoretisch waren sie sogar etwas langsamer geworden, da sie - im Gegensatz zum Pentium - für das FXCH etwas Zeit brauchen. Es gibt noch weitere Beispiele, das ein extrem optimierter Code auf anderen CPUs schlechter als der unoptimierte ist).
Der Unterschied in der Geschwindigkeit zwischen 16- und 32-Bit-Programmen besteht in der Größe der Speicherblöcke: Bei 16-Bit beträgt sie maximal 64KB, bei 32-Bit jedoch 4GB. Während ein 16-Bit-Programm also meist eine ganze Menge Blöcke braucht, reichen unter 32-Bit meist zwei oder drei (einer fürs Programm, einer für die Daten, eventuell noch eines für den Stack).
Die Prozessoren von Cyrix und AMD kommen mit dem erhöhten Verwaltungsaufwand besser zurecht. Da fast alle neueren Programme in 32-Bit sind (auch unter DOS, dank DOS4GW und DPMI), ist dies jedoch nicht mehr so bedeutend.
Ein weiterer Unterschied besteht in der Zeit, die für den Aufruf (FAR CALL; INT) externer Funktionen, z.B. des Betriebssystems durch das Programm, verbraucht wird. Allerdings sind diese Aufrufe generell recht zeitintensiv, so das man versucht, sie zu minimieren. Zudem kommen sie gerade in den Programmteilen, in denen Geschwindigkeit gefragt ist, äußerst selten vor.
Solange man sich nicht auf irgenwelche Spezialfälle (Raytracing mit PoVRay, etc.) spezialisiert, schlagen diese Unterschiede nicht allzu sehr auf die Programme durch.
Zudem ist der Flaschenhals im System meist nicht der Prozessor, sondern die allgemeinen Bandbreiten des Datentransfers vom Massenspeicher ins RAM oder hin zur Grafikkarte. Folglich ist das Geld besser in den anderen Komponenten als im Prozessor investiert
(na ja, als Geldanlage taugt ein PC wohl selbst bei größter Inflation kaum).
Außerdem wird handoptimierter Programmcode immer seltener (Quake I und spezielle Fraktalgeneratoren sind (leider) Ausnahmen). Es lohnt sich beim Programmieren mittlerweile eher, darauf zu achten, daß das Verarbeiten großer Datenmengen so in Blöcken geschieht, daß sie überwiegend in den Cache-Speichern ablaufen.