![]() |
Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
Moin Assarbad,
Zitat:
In ersterem Falle ginge das nur, wenn heruntergezählt wird, da Loop ja dekrementiert. So gesehen ist die Borland Variante bei eingeschalteter Optimierung immer EBX zu nehmen nicht gar so verkehrt. |
Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
Zitat:
Delphi-Quellcode:
und sie wird über eax gesteuert! (Optimierung ist eingeschaltet!)
for i := 1 to 20 do
begin end; |
Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
Zitat:
Code:
mittlerweile langsamer als ein
LOOP Schleifenbeginn
Code:
Und hierbei ist es egal welches Register benutzt wird.
DEC ECX
JNZ Schleifenbeginn Der Borland-Compiler nimmt ein Register, das gerade frei ist oder er macht eines frei. Welches er dann nimmt, ist hängt also zum einen vom vorhergehenenden Code und zum anderen vom Schleifenkörper ab. |
Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
Moin Motzi,
stimmt, das kann ich nachvollziehen. Allerdings hatte ich auch nicht mit leeren Schleifen getestet. @jbg: Kannst Du mir bitte mal die Quelle nennen, bezüglich der Ausführungsgeschwindigkeiten? Würde mich mal interessieren, und in den Intel P4 Manuals (24547011,24547111,24547211) habe ich darüber nichts gefunden. |
Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
Code:
Die Taktzyklen beziehen sich auf einen i486 und stammen aus dem Referenzhandbuch von Borland zu Turbo Assembler.
Befehle Taktzyklen
----------------------- DEC ECX 1 JNZ Beginn 3 LOOP Beginn 6 Hier ein Geschwindigkeitstest:
Delphi-Quellcode:
Auf P4 2GHz kommen im Schnitt folgende Werte zustande:
function RDTSC: Int64;
asm RDTSC end; function Test_Loop(Count: Integer): Int64; asm MOV ECX, EAX RDTSC // Startzeit ermitteln (Result=EDX:EAX) @@Repeat: LOOP @@Repeat end; function Test_DecJcc(Count: Integer): Int64; asm MOV ECX, EAX RDTSC // Startzeit ermitteln (Result=EDX:EAX) @@Repeat: DEC ECX JNZ @@Repeat end; procedure TForm1.Button1Click(Sender: TObject); const Count = $5fffffff; var t1, t2: Int64; begin try SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL); t1 := Test_Loop(Count); t1 := RDTSC - t1; t2 := Test_DecJcc(Count); t2 := RDTSC - t2; finally SetPriorityClass(GetCurrentProcess, NORMAL_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_NORMAL); end; Memo1.Lines.Add('LOOP : ' + IntToStr(t1)); Memo1.Lines.Add('DEC/Jcc: ' + IntToStr(t2)); Memo1.Lines.Add(''); end;
Code:
LOOP : 538596152
DEC/Jcc: 403735408 |
Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
Mion jbg,
danke. Ich dachte schon, Du hättest da vielleicht noch andere Quellen. Das Buch von Borland habe ich auch. War es nicht gerade der Loop Befehl, der bei AMD so schnell implementiert war, dass Win98 ins Trudeln kam und gepatcht werden musste? So gesehen könnte der Geschwindigkeitsvorteil sogar von der CPU abhängen. |
Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
Zitat:
Hier noch ein schnellere Variante der Test_DECJcc Funktion für den P4:
Code:
Ein "SUB ECX,1" ist auf einem P4 schneller als ein DEC ECX. Man staune, aber es ist so.
MOV ECX, EAX
RDTSC // Startzeit ermitteln (EDX:EAX) @@Repeat: SUB ECX, 1 JNZ @@Repeat |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz