 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 08.10.2006, 16:19 Titel: Profiling-Vergleich: verschiedene Bedingungen und Schleifen |
|
|
Weil ich mein derzeitiges Projekt möglichst auf Geschwindigkeit trimmen möchte (und teils aus Langeweile ) hab ich mal verschiedene Bedingungsstrukturen und Schleifen miteinander verglichen. Vielleicht interessiert es ja den Einen oder Anderen ein bisschen.
Code: | BEDINGUNGSSTRUKTUREN 5.98994 52.92%
IFTHEN_BLOCK 0.71797 6.34% 11.99%
IFTHEN_NOBLOCK 0.71606 6.33% 11.95%
SELECTCASE 0.71198 6.29% 11.89%
ASSEMBLER_BEDINGUNG 0.71086 6.28% 11.87%
SCHLEIFEN 5.31383 46.94%
ASSEMBLER_SCHLEIFE_PUSHPOP 1.71964 15.19% 32.36%
DOLOOP 0.88150 7.79% 16.59%
FORNEXT_PARAMETERUEBERGABE 0.81306 7.18% 15.30%
WHILEWEND 0.72100 6.37% 13.57%
FORNEXT 0.63797 5.64% 12.01%
ASSEMBLER_SCHLEIFE 0.48563 4.29% 9.14% |
Wie man sieht nehmen sich die Bedingungen rein gar nix. Allerdings habe ich bei der ASM-Bedingung eax vorher auf dem Stack gesichert, was aber wohl nicht notwendig ist, aber auch kaum etwas ausmacht.
Fazit: ASM-Code viel umständlicher und 0 Performancegewinn.
Hier der Code dazu:
Code: | sub IfThen_Block(a as integer)
if 0<a<25 then
b=1
elseif 24<a<50 then
b=2
elseif 49<a<75 then
b=3
end if
end sub
sub IfThen_NoBlock(a as integer)
if 0<a<25 then b=1
if 24<a<50 then b=2
if 49<a<75 then b=3
end sub
sub selectcase(a as integer)
select case a
case 1 to 24
b=1
case 25 to 49
b=2
case 50 to 74
b=3
end select
end sub
sub Assembler_Bedingung(a as integer)
dim b as integer
asm
push eax
mov eax,[a]
cmp eax,25
jl one
cmp eax,50
jl two
cmp eax,75
jl three
jg ende
one: mov [b], dword ptr 1
jmp ende
two: mov [b], dword ptr 2
jmp ende
three: mov [b], dword ptr 3
ende: pop eax
end asm
end sub |
Bei den Schleifen sieht es schon ein wenig anders aus. Als einfache Zählschleife macht sich natürlich FOR...NEXT (erwartungsgemäß) am besten. DO und WHILE sind ein wenig langsamer.
Inline-Assembler macht dagegen wenig Sinn, da durch das Pushen und Poppen von ecx (was nötig ist, da die Registerinhalte beim Wechsel zu FB-Code verloren gehen) die Schleife a****langsam wird.
Wenn man allerdings auf den Wechsel verzichten kann und alles innerhalb der Schleife auch in ASM schreibt, kann man durchaus noch ein wenig herausholen. Die ASM-Schleife braucht dabei nur 3/4 der Zeit von FOR...NEXT.
Hier der zugehörige Code:
Code: | sub ForNext
for i=1 to 30000
next
end sub
sub DoLoop
do
i=i+1
loop until i=29999
end sub
sub WhileWend
i=0
while i<30000
i=i+1
wend
end sub
sub Assembler_Schleife
asm mov ecx,29999
asm L1:
asm Loop L1
end sub
sub Assembler_schleife_pushpop
asm mov ecx,29999
asm L2: push ecx
asm pop ecx
asm Loop L2
end sub
sub ForNext_ParameterUebergabe(var as integer)
for i=1 to var
next
end sub |
Perhaps more coming soon... |
|
Nach oben |
|
 |
Dusky_Joe

Anmeldungsdatum: 07.01.2005 Beiträge: 1007 Wohnort: Regensburg/Oberpfalz
|
Verfasst am: 08.10.2006, 17:17 Titel: |
|
|
Hmm, recht interessant. Bei den Bedingungsstrukturen könntest du vielleicht noch SELECT CASE AS CONST einbauen - das funzt nur bei Integers, ist aber doch um einiges schneller, heißts zumindest in der en. Doku.
Interessant ist, dass do...loop so viel langsamer ist als while...wend; bei beiden muss i mit einer konstanten verglichen werden, und ansonsten dachte ich immer, dass do mehr oder weniger ein extendet alias von while wäre...
Du kannst ja auch mal die -r Option einschalten, um zu vergleichen, wie FB den code nach ASM umsetzt. Vllt kannst du so auch einen günstigeren Walkaround erarbeiten, als das PUSH/POP?
Viel Spaß dabei.
Have a nice day
Ciao _________________ fully biological degradable
Once, the big wave arrives, you've got two ways, you can go:
Either, you ride it, or you don't do.
But, if you don't ride, you'll never know wether you'd have gone wet. |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 08.10.2006, 18:41 Titel: |
|
|
Hi, hier push und pop einzusetzen ist überflüssig, da der Assemblerteil nicht unterbrochen wird.
Code: | sub Assembler_schleife_pushpop
asm mov ecx,29999
asm L2: push ecx
asm pop ecx
asm Loop L2
end sub |
versuch mal:
Code: | sub Assembler_schleife_jnz
asm mov ecx,29999
asm L2: dec ecx
asm jnz L2
end sub | sollte beim Pentium schneller sein.
Gruß Volta _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 08.10.2006, 19:13 Titel: |
|
|
@Volta: Ich habe absichtlich nichts in die Schleifen gepackt, damit sie besser vergleichbar sind. Ausserdem ist egal, ob jnz oder loop. Kommt das gleiche bei raus :
Code: | .globl _ASSEMBLER_SCHLEIFE_LOOP@0
_ASSEMBLER_SCHLEIFE_LOOP@0:
push ebx
push esi
push edi
.Lt_0009:
mov ecx,29999
L2: dec ecx
jnz L2
.Lt_000A:
pop edi
pop esi
pop ebx
ret
.balign 16
.globl _ASSEMBLER_SCHLEIFE_JNZ@0
_ASSEMBLER_SCHLEIFE_JNZ@0:
push ebx
push esi
push edi
.Lt_000B:
mov ecx,29999
L1: dec ecx
jnz L1
.Lt_000C:
pop edi
pop esi
pop ebx
ret
.balign 16 |
Zu dem ominösen SELECT CASE AS CONST:
Ich habe das Beispiel aus der engl. Doku genommen und verglichen. Dabei ist es tatsächlich schneller:
Code: |
SELECTCASE 0.05542 26.48% 26.48%
SELECTCASE_CONST 0.04340 20.74% 20.74% |
Allerdings relativiert sich das bei großen TO-Spannen. Dann werden häßlicherweise unendlich viele Sprungziele erzeugt.
Was mich auch positiv überrascht hat, ist, dass Ausdrücke wie x=x+1 oder auch x=x-(20-21) in das schnellere INC übersetzt werden. |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|