Autor Beitrag
Arno-Wien
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 33

xp

BeitragVerfasst: Mi 30.11.05 22:31 
Erzeugung eines Apfelmännchenbildes:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
PROCEDURE apf_beliebiger_ausschnitt;
VAR m,n,i:longint;
p:pbytearray;
xwert,ywert,x_konst,x1_konst,y_konst,y2wert,xqu,yqu,summe,
deltax,deltay:extended;

BEGIN
  ausschnitt_check:=true;
  deltax:=(c_reel2-c_reel1)/639;
  deltay:=(c_imag2-c_imag1)/479;
  y_konst:=c_imag1-deltay;
  m:=0;
  REPEAT
    p:=a_bild.ScanLine[m];
    y_konst:=y_konst+deltay;
    x_konst:=c_reel1-deltax;
    FOR n:=0 TO 639 DO
    BEGIN
      x1_konst:=x_konst+deltax;
      x_konst:=x1_konst;
      xwert:=0.0;
      ywert:=0.0;
      xqu:=0.0;
      yqu:=0.0;
      color:=0;
      REPEAT
        y2wert:=xwert*ywert;
        ywert:=y2wert+y2wert-y_konst;
        xwert:=xqu-yqu-x_konst;
        xqu:=xwert*xwert;
        yqu:=ywert*ywert;
        summe:=xqu+yqu;
        color:=succ(color)
      UNTIL (summe > maxsum) OR (color = colormax);
      IF form7.checkbox6.checked THEN
      BEGIN
        IF (color >= colormin) OR (color = colormax) THEN
        begin
          i:=3*n;
          p[i]:=farbe_blau;
          p[i+1]:=farbe_gruen;
          p[i+2]:=farbe_rot;
          form7.canvas.pixels[n,m]:=farben
        end
      END ELSE
      BEGIN
        IF (color <= colormin) OR (color = colormax) THEN
        begin
          i:=3*n;
          p[i]:=farbe_blau;
          p[i+1]:=farbe_gruen;
          p[i+2]:=farbe_rot;
          form7.canvas.pixels[n,m]:=farben
        end
      END
    END;
    m:=succ(m);
    Application.processMessages
  UNTIL (m = 480) or ende;
  daten_aktualisieren(werte_apf_alt);
  BitBlt(bild_apf.canvas.handle,0,0,640,480,
         a_bild.canvas.handle,0,0,SRCCOPY)
END;



Mein Problem ist die Schleife :

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
      REPEAT
        y2wert:=xwert*ywert;
        ywert:=y2wert+y2wert-y_konst;
        xwert:=xqu-yqu-x_konst;
        xqu:=xwert*xwert;
        yqu:=ywert*ywert;
        summe:=xqu+yqu;
        color:=succ(color)
      UNTIL (summe > maxsum) OR (color = colormax);



Ab 10 000 Iterationen (colormax) wird es mühsam.
Ab 100 000 öd.

Die Zahlen in diesem Abschnitt produzieren keine Fehler.

Gibt es eine Lösung ( Assembler )

Arno

Moderiert von user profile iconUGrohne: Delphi-Tags hinzugefügt.


Zuletzt bearbeitet von Arno-Wien am Mi 30.11.05 23:25, insgesamt 1-mal bearbeitet
Grishnak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Mi 30.11.05 22:34 
Bitte setze deinen Quellcode in [delphi]...[/delphi] und rücke ihn augenfreundlich ein. So ist er sehr schlecht les- und verstehbar!

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Do 01.12.05 01:13 
Verwende mal Double anstatt von Extended, das bringt schon ein paar Prozentchen.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Do 01.12.05 08:56 
Hallo,

vorgestern war doch bei Newsfeed genau dazu eine Meldung.. using SSE,SS2..
www.codeproject.com/cpp/fractalsSSE.asp
oder dort angegeben:
sourceforge.net/projects/ffff/
Da ist ausreichend viel assembler drin.

Gruss Horst
FFFF3.exe auf meinem alten Duron 18000 applebred
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
 Sys perf timer freq: 1193180 Hz
 size:  500*500
 maxiters:      9999
 rangex:        -2.00 to 1.00
 rangey:        -1.50 to 1.50
  SSE benchmark:
    1.867 sec
    225.249 MegaIters/sec
  SSE2 benchmark:
    Not supported.
  3DNow! benchmark:
    2.915 sec
    144.245 MegaIters/sec
  FPU ASM benchmark:
    4.811 sec
    87.398 MegaIters/sec
  FPU C benchmark:
    13.523 sec
    31.093 MegaIters/sec
  GPU VertexProgram benchmark (beta! maxiters=10) on GDI Generic:
ATI Vertex Program: Required extensions are not supported    Not supported.
  GPU FragmentProgram benchmark (beta! maxiters=20) on GDI Generic:
ARB Fragment Program: Required extensions are not supported    Not supported.
Kroko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1284

W98 W2k WXP
Turbo D
BeitragVerfasst: Do 01.12.05 10:49 
ich habe mal mit deinen Quellcode ein wenig rumgespielt (zwar aufwändig, weil ein paar Teile fehlen) und dabei ist mir folgendes aufgefallen:
(1) du nimmst Scanline,damit du schnell auf darauf zugreifen kannst, und rifst dann doch wiederform7.canvas.pixels[n,m]:=farben langsam auf irgendein Canvas zuzugreifen
(2) die Startwerte für x und y sind im allgemeinen nicht Null, sonder X_konst und Y_konst
(3) Application.ProcessMessages verlangsamt alles, daher vielleicht nur jede 2.(oder 4.Zeile) aufrufen
(4) /640 und /640 muss bei der Delta-Berechnung heißen
(5)
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
  deltax := (c_reel2-c_reel1)/640;
  deltay := (c_imag2-c_imag1)/480;
  y_konst := c_imag1;
  m := 0;
  repeat
    P := B.ScanLine[m];
    I := 0;
    x_konst := c_reel1;

    for N := 0 to 639 do
    begin
      xwert:=0.0;
      ywert:=0.0;
      xqu:=0.0;
      yqu:=0.0;
      Hcolor:=0;
      REPEAT
        y2wert := xwert*ywert;
        ywert := y2wert+y2wert-y_konst;
        xwert := xqu-yqu-x_konst;
        xqu := xwert*xwert;
        yqu := ywert*ywert;
        Inc (HColor);
      UNTIL (xqu+yqu > maxsum) OR (Hcolor= colormax);

          p[i]:= (HColor shr 16) and $FF;
          p[i+1]:= (HColor shr 8) and $FF;
          p[i+2]:= HColor and $FF;
          Inc (I,3);

          
      x_konst:=x_konst+deltax;
    END;
    y_konst:=y_konst+deltay;
    Inc (M);
    Application.processMessages
  UNTIL (m = 480) or ende;
  //daten_aktualisieren(werte_apf_alt);
  BitBlt (canvas.handle,0,0,640,480,
          B.Canvas.handle,0,0,SRCCOPY);

damit habe ich folgende Zeiten erreicht

ColorMax=5000
reell [-1.6;2.4]
imag [-1.5;1.5]

Deine Routine: Extended >13s
Deine Routine: Double >8s
meine Routine: Double >5,8s


(6) die meiste Zeit geht im Konvergenzgebiet drauf, da gibt es auch Kriterien, die zeigen das man im Konvergenzgebiet ist (ist bei FRACTINT) erklärt

(7) Viel Spaß noch!

_________________
Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 01.12.05 11:09 
user profile iconKroko hat folgendes geschrieben:
ich habe mal mit deinen Quellcode ein wenig rumgespielt (zwar aufwändig, weil ein paar Teile fehlen) und dabei ist mir folgendes aufgefallen:


user profile iconKroko hat folgendes geschrieben:
(4) /640 und /640 muss bei der Delta-Berechnung heißen

/640 und /480 stimmt schon so, wie er's hat, weil man 639 / 479 Zwischenräume hat. Der Unterschied ist aber marginal.

user profile iconKroko hat folgendes geschrieben:
(5)
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
  deltax := (c_reel2-c_reel1)/640;
  deltay := (c_imag2-c_imag1)/480;
  y_konst := c_imag1;
  m := 0;
  repeat
    P := B.ScanLine[m];
    I := 0;
    x_konst := c_reel1;

    for N := 0 to 639 do
    begin
      xwert:=0.0;
      ywert:=0.0;
      xqu:=0.0;
      yqu:=0.0;
      Hcolor:=0;
      REPEAT
        y2wert := xwert*ywert;
        ywert := y2wert+y2wert-y_konst;

        xwert := xqu-yqu-x_konst;
        xqu := xwert*xwert;
        yqu := ywert*ywert;
        Inc (HColor);
      UNTIL (xqu+yqu > maxsum) OR (Hcolor= colormax);

          p[i]:= (HColor shr 16) and $FF;
          p[i+1]:= (HColor shr 8) and $FF;
          p[i+2]:= HColor and $FF;
          Inc (I,3);

          
      x_konst:=x_konst+deltax;
    END;
    y_konst:=y_konst+deltay;
    Inc (M);
    Application.processMessages
  UNTIL (m = 480) or ende;
  //daten_aktualisieren(werte_apf_alt);
  BitBlt (canvas.handle,0,0,640,480,
          B.Canvas.handle,0,0,SRCCOPY);


Zeile 18 und 19 kann man besser als
ausblenden Delphi-Quelltext
 
18:
{ ... }
ywert := 2 * xwert * ywert - y_konst;

schreiben und y2wert komplett entfernen. Dadurch entfallen potentiell 3-4 Speicherzugriffe, was auch noch mal ein wenig Performance bringen sollte.

BTW: Mit Single läuft's noch'n bissl schneller.

P.S.: Topic ist ne Fortsetzung des.Algo&Opti-Threads "Beschleunigen einer Multiplikation".

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Spaceguide
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 552


(D3/D7/D8) Prof.
BeitragVerfasst: Do 01.12.05 11:52 
user profile iconKroko hat folgendes geschrieben:

(3) Application.ProcessMessages verlangsamt alles, daher vielleicht nur jede 2.(oder 4.Zeile) aufrufen


Am besten die Berechnung gleich ordentlich in einen Thread auslagern. Application.ProcessMessages aufzurufen ist in meinen Augen einfach nur Pfusch.
Der Jan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 98

Win2k prof, WinXP prof, Linux
D6 Prof, BCB4 Std, BCB6 Ent, BDS 2006 Ent
BeitragVerfasst: Do 01.12.05 11:54 
Ich habe mir den Source zwar nicht so genau angeschaut, da ich mich aber vor ein paar Jahren selbst mal mit Fraktalen beschäftigt habe und entsprechend versucht habe, die Vorgänge zu beschleunigen, kann ich prinzipiell folgendes sagen: Du kannst in diesem Algorithmus zwar hier und da eine Kleinigkeit verbessern, aber den grossen Erfolg in Bezug auf Geschwindigkeit wirst du damit nicht haben.
Statt dessen solltest du versuchen, den Algorithmus als solches abzuändern.
Kleines Beispiel (im Vorab schon sorry für die "schlechten" Fachausdrücke"): Du berechnest die Iterationstiefe (Farbe) für jeden Punkt. Warum? Wenn (im Inneren des Fraktals) die Umrandung eines Rechtecks eine Farbe hat, hat sein Inhalt auch diese Farbe. Allein damit läßt sich die Berechnung, je nach dem, wie "tief" man im Fraktal ist, um ein mehrfaches Beschleunigen.

_________________
Gruß, Jan
Kroko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1284

W98 W2k WXP
Turbo D
BeitragVerfasst: Do 01.12.05 12:48 
sorry, das in den Zeilen 18/19 habe auch übersehen, Geschwindigkeitsvorteil gibts später, muss jetzt arbeiten :cry:

_________________
Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!