Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi FOR-Schleifenvariable muss eine lokale Variable sein. Warum? (https://www.delphipraxis.net/7877-schleifenvariable-muss-eine-lokale-variable-sein-warum.html)

Christian Seehase 24. Aug 2003 14:15

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Moin Assarbad,

Zitat:

Zitat von Assarbad
Andere Compiler (zB VC) nehmen übrigens tatsächlich ECX, ist ja schließlich auch das Counter-Register

Allerdings würde dies den Compiler ein klein wenig komplizieren, da in diesem Falle extra unterschieden werden müsste, ob denn nun der Schleifenzähler innerhalb der Schleife benutzt wird, oder nicht.
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.

Motzi 24. Aug 2003 14:50

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Zitat:

Zitat von Christian Seehase
So gesehen ist die Borland Variante bei eingeschalteter Optimierung immer EBX zu nehmen nicht gar so verkehrt.

Tun sie aber nicht.. hab mir mal angeschaut wie diese Schleife übersetzt wird:
Delphi-Quellcode:
for i := 1 to 20 do
begin
end;
und sie wird über eax gesteuert! (Optimierung ist eingeschaltet!)

jbg 24. Aug 2003 15:56

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Zitat:

Zitat von Christian Seehase
In ersterem Falle ginge das nur, wenn heruntergezählt wird, da Loop ja dekrementiert.

Zudem ist ein
Code:
LOOP Schleifenbeginn
mittlerweile langsamer als ein
Code:
DEC ECX
JNZ Schleifenbeginn
Und hierbei ist es egal welches Register benutzt wird.

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.

Christian Seehase 24. Aug 2003 17:14

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.

jbg 24. Aug 2003 18:00

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Code:
Befehle     Taktzyklen
-----------------------
DEC ECX     1
JNZ Beginn  3

LOOP Beginn 6
Die Taktzyklen beziehen sich auf einen i486 und stammen aus dem Referenzhandbuch von Borland zu Turbo Assembler.


Hier ein Geschwindigkeitstest:
Delphi-Quellcode:
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;
Auf P4 2GHz kommen im Schnitt folgende Werte zustande:
Code:
LOOP  : 538596152
DEC/Jcc: 403735408

Christian Seehase 24. Aug 2003 18:17

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.

jbg 24. Aug 2003 18:24

Re: FOR-Schleifenvariable muss eine lokale Variable sein. Wa
 
Zitat:

Zitat von Christian Seehase
So gesehen könnte der Geschwindigkeitsvorteil sogar von der CPU abhängen.

Das hängt sie immer. Die Intel Chip Architekten haben den LOOP Befehl einfach vernachlässigt. Man kann es auch so sehen, dass Intel Prozesooren im Druchschnitt alle "höheren" (CISC) Befehle viel langsamer ausführen als mehrere/viele "niedrige" (RISC) Befehle.

Hier noch ein schnellere Variante der Test_DECJcc Funktion für den P4:
Code:
        MOV    ECX, EAX
        RDTSC            // Startzeit ermitteln (EDX:EAX)
@@Repeat:
        SUB    ECX, 1
        JNZ    @@Repeat
Ein "SUB ECX,1" ist auf einem P4 schneller als ein DEC ECX. Man staune, aber es ist so.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:10 Uhr.
Seite 3 von 3     123   

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