Geschwindigkeit optimieren ... ?
-
In diversen Grafiktests (vor allem im guten alten ModeX) hab ich unterschiedliche Routinen eingesetzt: den Aufruf des Interrupt 10h, eine direkte Adressierung für einen Pixel und zu guter letzt für unterschiedliche Funktionen (Rechteck, Linie, ...) speziell optimierte Routinen.
Als Vergleich hab ich dann noch die Multiplikation durch ein Bitshifting und ne Addition ersetzt, also
einMOV ax,320
MUL [y]
mov di,axwurde zu
mov di,[y]
mov cl,6
shl di,cl
mov ax,[y]
xchg ah,al
add di,axauch wenn er länger ist, so wird der zweite Code auf meinen älteren Rechnern (386, 486) schnell ausgeführt, als der erste (wegen der Umgehung der Multiplikation).
Als ich das Prog aber auf nem AMD K2 - 450 laufen lies, war die erste Routine schneller fertig, als die zweite...
Kanns jetzt sein, dass durch das immer Voranschreitende Anpassen der Prozessoren die "alten, optimierten" Routinen nun langsamer sind als die Standardroutinen?mfg ETNA
-
Fangen wir mal mit den älteren prozessoren an. Da ergeben sich als Takzeiten:
8086 | 80186 | 80286 | 80386 | 80486 | Pentium | | | | | einzeln tatsächlich ----------------------+-------+-------+-------+-------+------------------------ mov ax,320 4 | 3-4 | 2 | 2 | 1 | 1 UV 1 mul [y] 129-144 | 41-43 | 24 | 12-25 | 13-25 | 11 NP 11 mov di,ax 2 | 2 | 2 | 2 | 1 | 1 UV 1 ----------------------+-------+-------+-------+-------+------------------------ Total 135-150 | 46-49 | 28 | 16-29 | 15-27 | 13 8086 | 80186 | 80286 | 80386 | 80486 | Pentium | | | | | einzeln tatsächlich ----------------------+-------+-------+-------+-------+------------------------ mov di,[y] 17 | 12 | 5 | 4 | 1 | 1 UV 1 mov cl,6 4 | 3-4 | 2 | 2 | 1 | 1 UV shl di,cl 32 | 11 | 11 | 3 | 3 | 4 NP 4 mov ax,[y] 17 | 12 | 5 | 4 | 1 | 1 UV 1 xchg ah,al 3 | 3 | 2 | 2 | 1 | 1 UV 1 add di,ax 3 | 3 | 2 | 2 | 1 | 1 UV 1 ----------------------+-------+-------+-------+-------+------------------------ Total 76 | 44-45 | 27 | 17 | 8 | 8
Auf den AMD-Prozessoren wird das ganze nun wesentlich interessanter, weil die ja die Befehle sowieso erstmal in eine interne Microcode-Struktur umwandeln. Daher ist ne genaue Taktzyklen-berechnung da auch schwer, ich versuch mich mal grob
Auf AMD-Prozessoren unterscheidet man DirectPath- und VectorPath-Anweisungen. DirectPath-Anweisungen lassen sich direkt in einen Microcode umwandeln und können schnell vom Prozessor bearbeitet werden. VectorPath-Anweisungen müssen erst durch nen Dekoder und brauchen daher nen Moment länger.Taktzyklen Path --------------------------------------------------- mov ax,320 1 DirectPath mul [y] 8 VectorPath mov di,ax 1 DirectPath --------------------------------------------------- Total 10 (keine Parallelisierung, da jede Instruktion von der vorherigen abhängt) Taktzyklen Path --------------------------------------------------- mov di,[y] 3 DirectPath mov cl,6 1 DirectPath shl di,cl 1 DirectPath mov ax,[y] 3 DirectPath xchg ah,al 2 VectorPath add di,ax 1 DirectPath --------------------------------------------------- Total 11 Bestmögliche Parallelisierung: | T a k t z y k l e n | | 1 || 2 || 3 || 4 || 5 | +----------++----------++----------++-----------++-----------+ [----------- mov di,[y] -----------][ shl dl,cl ][ add di,ax ] [ mov cl,6 ][mov ax,[y]][xchg ah,al]-------------------------- 5 Taktzyklen
Ergo: Prinzipiell ist die zweite Lösung immernoch die günstigere. Entweder hast du dich vermessen
oder die Cachepolitik von AMD-Prozessoren sind im ersten Fall immernoch günstiger und verlangsamern im zweiten Fall die Berechnung
Zusatz:
Ich hab mal eben die beiden Sources in ein kelines Prog gebaut, den Code jeweils 0x0fffffff-malausführen lassen und komme auf 2 Sekunden für den ersten und 1,8 Sekunden für den zweiten. Also auf meinem AMD Duron funktioniert die Berechnung
[ Dieser Beitrag wurde am 03.09.2002 um 02:36 Uhr von TriPhoenix editiert. ]
-
Ich bin total beeindruckt, wo hast du denn diese Infos her über die Parallelisierung her, hab ich noch nie so genau verstanden...
Die Messung verlief immer gleich: Die Bereichnung wurde mehrere tausend Male wiederholt und dann hab ich einfach den Wert der Uhr (Unterschiede zwischen Start und Ende des Progs - INT 1Ahex) ausgelesen.
Die Algorithmen waren bei den meisten neuen Rechnern ziemlich gleich, nur der AMD 450 hatte bei Nr. 2 diesen perversen Vorsprung.
Mein Duron 750 verhält sich hingegen wieder normal, obwohl er (wie auch der AMD 450) bei gefüllten Rechtecken die eigens optimierte Assemblerschleife gar nicht mehr sonderlich schneller erscheinen lässt, als wenn ich nur ne einzelne PutPixel-Routine habe und die von ner externen Schleife aus (mit Koordinaten übergabe) aufrufen lasse...
is schon wirklich komisch, dass die Optimierungen jetzt schon fast langsamer sind als die "einfachen" Codes...
Beim 386 war der Beschleunigungseffekt am höchsten, hat micht total gefreut, neue Prozessoren sind da irgend wie eine Entäuschung, da freut man sich endlich den ASM ein bisschen zu verstehen und dann sowas...
Jedenfalls Danke für die INFOmfg ETNA
-
Original erstellt von etna:
**Ich bin total beeindruckt, wo hast du denn diese Infos her über die Parallelisierung her, hab ich noch nie so genau verstanden...
**AMD Athlon Processor Optimization Guide
(Und ne handvoll Leserei in diversen Seiten/Büchern ;))
**
Beim 386 war der Beschleunigungseffekt am höchsten, hat micht total gefreut, neue Prozessoren sind da irgend wie eine Entäuschung, da freut man sich endlich den ASM ein bisschen zu verstehen und dann sowas...
**Tja...moderne Prozessoren sind leider so undurchsichtig für den Programmierer konstuiert worden, dass man wahrschheinlich mit garnichts mehr rechnen darf. Eine mehrstufige Pipeline, dazu ein paar merkwürdige Microcode-Umsetzungen (die Intel natürlich genauso wie AMD macht) und noch ein unkontrollierbarer Cache, da soll noch mal jemand sagen, ein Computer wäre deterministisch
[ Dieser Beitrag wurde am 03.09.2002 um 02:49 Uhr von TriPhoenix editiert. ]