Martin66119 hat geschrieben:ich habe den Codevorschlag nun mal mit meinen "langsames" Netbook getestet.
[...]
ASM = 1360ms
PB = 1570ms
Bei mir ist die Version von _sivizius auf einem 1 Jahr alten Mac Mini Server (2,6 GHz Intel Core i7) mit Mac OS X
etwa 1/3 schneller als PB (197ms : 303ms).
Auf einem etwa 5 Jahre alten Intel Core2 Quad Q9450 @ 2,66 GHz mit Windows 8.1 ist seine Version
allerdings langsamer als PB (630ms : 540ms), was an der Verwendung des langsamen 'loop' Befehls liegen könnte.
Meine eigene Anpassung von Makkes Code mit ASM-Registern ist auf beiden Computern etwa 3mal so schnell wie PB:
Alter Core2: 169ms : 554ms
Mac Core i7: 90ms : 303ms
Der größte Unterschied ist, dass alle Variablen in ASM-Registern gehalten werden. Kann man natürlich weiter optimieren.
Gegenüber der originalen Version von Makke wurde der Zugriff auf Speichervariablen innerhalb der Schleife weg-optimiert.
Das i = n*2 (MOV eax, n : MOV ebx, 2 : MUL ebx : MOV i, eax) wurde durch ein simples Links-Shiften mit 1 ersetzt.
Der Sprung 'JE l_equal' wurde entfernt, da die erste If-Bedingung einfach durchfallen kann, ohne springen zu müssen.
Code: Alles auswählen
Define.l d, n, m, i, j, t
m = 100000000
t = ElapsedMilliseconds()
EnableASM
MOV edx, m ; edx = m
MOV ecx, 1 ; ecx (n) = 1
for_loop_1:
MOV eax, ecx ; eax (i) = ecx (n)
SHL eax, 1 ; eax * 2
MOV ebx, edx ; ebx (j) = edx (m) - kann man verschieben, direkt vor das label 'for_loop_1'
CMP eax, ebx ; compare eax (i) with ebx (j)
JL l_less ; Jump if Less
JG l_greater ; Jump if Greater
equal: ; Equal
MOV esi, 0 ; esi (d) = 0
JMP l_finish
greater:
MOV esi, 1 ; esi (d) = 1
JMP l_finish
less:
MOV esi, -1 ; esi (d) = -1
finish:
INC ecx ; ecx (n) + 1 \
CMP ecx, edx ; compare ecx (n) with edx (m) |= Next
JNA l_for_loop_1 ; Jump if Not Above /
MOV i, eax ; i = eax
MOV j, ebx ; j = ebx
MOV n, ecx ; n = ecx
MOV d, esi ; d = esi
DisableASM
MessageRequester("Zeit",Str(ElapsedMilliseconds()-t) + " - i=" + i + " j=" + j + " d=" + d + " n=" + n, #PB_MessageRequester_Ok)
t = ElapsedMilliseconds()
For n = 1 To m
i = n*2
j = m
If i = j
d = 0
ElseIf i > j
d = 1
Else
d = -1
EndIf
Next
MessageRequester("Zeit",Str(ElapsedMilliseconds()-t) + " - i=" + i + " j=" + j + " d=" + d + " n=" + n, #PB_MessageRequester_Ok)