Entwickler-Ecke
Algorithmen, Optimierung und Assembler - For Anweisung spinnt
juelin - Do 02.09.10 12:08
Titel: For Anweisung spinnt
ich glaube ich spinne!!??
ich habe eine FOR Anweinsung im Programm (DELPHI 7)
for l:=1 to 99 do
l ist vom Typ integer
Nun mach die Scleife folgendes:
l fängt bei 99 an und wird bei jedem Durchlauf vermindert (99, 98, 97......1)
wie bei DOWNTO
Nun stehe ich da und kann nicht weiter.
Hat da jemand eine Idee??
Gruss
Jürgen
Moderiert von
Narses: Topic aus Programmierwerkzeuge verschoben am Fr 03.09.2010 um 00:26
Marc. - Do 02.09.10 12:19
juelin hat folgendes geschrieben : |
for l:=1 to 99 do
l ist vom Typ integer
Nun mach die Scleife folgendes:
l fängt bei 99 an und wird bei jedem Durchlauf vermindert (99, 98, 97......1)
wie bei DOWNTO |
Hast Du noch etwas mehr Code? Verwechselst Du vielleicht I(i) mit l(L)?
Intern zählt Delphi allerdings bei For-Schleifen idT. nach unten. :P
ALF - Do 02.09.10 12:20
juelin hat folgendes geschrieben : |
Nun stehe ich da und kann nicht weiter.
Hat da jemand eine Idee?? |
Wo kommst Du denn nicht weiter?
Du hast doch die 2 Möglichkeiten:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| For i:= 1 to 99 do begin end;
For i:= 99 downto 1 do begin end; |
Wo liegt das Problem?
Gruss Alf
mh.. zu langsam :P
elundril - Do 02.09.10 12:22
Naja, nicht ganz. Intern wird die Schleife umgekehrt durchlaufen (Compileroptimierung). Sollte aber für dich als Programmierer nichts ändern.
lg elundril
Nersgatt - Do 02.09.10 12:45
Aber nur, wenn man nicht auf i zugreift. Daher ist es egal. Sobald man auf i zugreift, läuft die Schleife "richtig rum".
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var i : integer; begin
for i := 1 to 5 do showMessage('Hallo');
for i := 1 to 5 do ShowMessage(intToStr(i));
end; |
Einfach mal die beiden Schleifen im Debugger durchsteppen und dabei den Wert von i beobachten.
elundril - Do 02.09.10 12:57
Lazarus optimiert das anscheinend gar nicht? Zumindest wird bei diesem Quelltext die Schleife richtig rum durchlaufen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| var i: integer; p: pointer; begin p := @i; for i := 0 to 99 do begin Showmessage(IntToStr(Integer(p^))); end; end; |
lg elundril
Nersgatt - Do 02.09.10 13:07
Delphi (2010) durchläuft sie auch richtig rum.
thepaine91 - Do 02.09.10 13:18
Delphi 6 durchläuft sie auch richtig rum (selber Code wie bei Elundril).
elundril - Do 02.09.10 13:22
Also checkt der compiler auch wenn n Pointer auf die Laufvariable zeigt und läuft dann richtig rum? Oder wie wird entschieden wann optimiert wird?
lg elundril
Dude566 - Do 02.09.10 13:35
elundril hat folgendes geschrieben : |
Lazarus optimiert das anscheinend gar nicht? Zumindest wird bei diesem Quelltext die Schleife richtig rum durchlaufen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var i: integer; p: pointer; begin p := @i; for i := 0 to 99 do begin Showmessage(IntToStr(Integer(p^))); end; end; |
lg elundril |
Warum der Pointer, man kann doch auch direkt i ausgeben.
elundril - Do 02.09.10 13:39
weil ich mir dachte das der Compiler so nicht checkt das ich auf i zugreife und dann eher geneigt ist die schleife zu optimieren.
lg elundril
Nersgatt - Do 02.09.10 13:39
Die Idee von Elundril war wohl, den Compiler damit zu überlisten, dass der die Schleife trotz dem Zugriff auf i optimiert.
Dude566 - Do 02.09.10 13:43
Nach welchem Schema und wieso sollte der Compiler denn eine solche Schleife optimieren, wird sie dadurch schneller?
Nersgatt - Do 02.09.10 13:44
Lies doch mal den Link von Luckie. Da ist es erklärt, warum und wieso.
Delete - Do 02.09.10 13:44
elundril hat folgendes geschrieben : |
Also checkt der compiler auch wenn n Pointer auf die Laufvariable zeigt und läuft dann richtig rum? Oder wie wird entschieden wann optimiert wird? |
Kann ich dir leider nicht sagen. Aber nimm mal meinen sinnlosen Code aus meinem Artikel und lass den mal unter Lazarus compilieren und gucke, was passiert. Und achte darauf, dass die Optimierung aktiviert ist.
elundril - Do 02.09.10 13:47
Dude566 hat folgendes geschrieben : |
Nach welchem Schema und wieso sollte der Compiler denn eine solche Schleife optimieren, wird sie dadurch schneller? |
Wie in
Luckie seinem Link schon erklärt wird, wird bei einer Optimierten schleife im assamblercode nicht mittels cmp sonder mittels jnz die schleifenbedingung überprüft. Dadurch spart man sich einige Taktzyklen weil man ja dann nicht erst das ergebnis von cmp auswerten muss sondern gleich springt. Ich glaub in der DP wurde mal gesagt das man bei einer normalen schleife 6 Zyklen braucht, wobei eine optimierte schleife nur 4 braucht.
@
Luckie: Ne, Im asm-Code keine Spur von einem jnz. Jedoch könnte Lazarus jl verwenden, hab ich leider nicht sogut erkennen können (einerseits wegen mangelnder ASM erfahrung, andererseits weil das asm-fenster auch anders ist als bei delphi)
lg elundril
Gammatester - Do 02.09.10 14:06
elundril hat folgendes geschrieben : |
Ich glaub in der DP wurde mal gesagt das man bei einer normalen schleife 6 Zyklen braucht, wobei eine optimierte schleife nur 4 braucht.
|
Na ja, auf Geschwindiglkeit ist das nicht gerade optimiert. Wie
Agner Fog [
http://www.agner.org/optimize/] schreibt:
Zitat: |
16.2 INC and DEC (all Intel processors)
The INC and DEC instructions do not modify the carry flag but they do modify the other arithmetic flags. Writing to only part of the flags register costs an extra µop on P4 and P4E. It can cause a partial flags stalls on other Intel processors if a subsequent instruction reads the carry flag or all the flag bits. On all processors, it can cause a false dependence on the carry flag from a previous instruction.
Use ADD and SUB when optimizing for speed.
Use INC and DEC when optimizing for size or when no penalty is expected. |
Delete - Do 02.09.10 14:26
elundril hat folgendes geschrieben : |
Wie in Lucky |
Wer ist dieser Luck
y? Ich glaube, mit dem muss ich mich mal näher befassen. :mrgreen:
elundril - Do 02.09.10 14:30
Na der Typ der schneller schießt als sein schatten, Lucky Luke. Da es jetzt keine Cowboys mehr gibt hat er vom Arbeitsamt ne umschulung zum Programmierer bekommen. :mrgreen:
Sorry. :oops:
jaenicke - Do 02.09.10 22:51
Nersgatt hat folgendes geschrieben : |
Delphi (2010) durchläuft sie auch richtig rum. |
Hast du im Assemblercode geschaut?
Dass es im Debugger falsch herum angezeigt wurde, war früher ja ein Fehler, weil der schlicht nichts von der Optimierung wusste. Wenn du also nur im Debugger geschaut hast, kann es auch sein, dass der korrigiert wurde und den richtigen Wert aus dem optimierten berechnet (wie ich es eigentlich von Anfang erwartet hätte).
Nersgatt - Fr 03.09.10 07:23
Ich muss sagen, dass ich nicht in der ASM-Welt zuhause bin.
Folgender Code:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var i: integer; p: pointer;
begin begin p := @i; for i := 0 to 99 do begin Writeln(IntToStr(Integer(p^))); end; end; end. |
Wenn ich das richtig sehe, wird also hochgezählt.
juelin - Fr 03.09.10 07:32
Also ich habe die fOR Schleife im Debug-Modus im Einzelschritt durch laufen
und jeweils die Variable l(L) abgefragt.
For l:=1 to 99 do
begin
nt[l]:=x;
end;
Da lief es rückwärts (99, 98, 97 ..... 1);
Aber das Programm läuft jetzt richtig.
Warum auch immer.
Problem gelößt.
Gruss
Jürgen
jaenicke - Fr 03.09.10 08:11
Nersgatt hat folgendes geschrieben : |
Wenn ich das richtig sehe, wird also hochgezählt. |
Richtig, esi wird hochgezählt, mit cmp verglichen und je nach dem Ergebnis mit jnz zurück zum Anfang gesprungen, wenn der Wert nicht erreicht ist. Allerdings greifst du auch auf die Variable zu und ich traue dem Compiler durchaus die "Intelligenz" zu dies hier zu erkennen.
juelin hat folgendes geschrieben : |
Aber das Programm läuft jetzt richtig. |
Das tut es immer, du siehst diesen Wert ja nur im Debugger falsch. Wenn du die Optimierung ausschaltest, stimmt es auch da.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!