| Autor |
Beitrag |
Arno-Wien
      
Beiträge: 33
xp
|
Verfasst: Mi 30.11.05 22:31
Erzeugung eines Apfelmännchenbildes:
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 :
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 UGrohne: Delphi-Tags hinzugefügt.
Zuletzt bearbeitet von Arno-Wien am Mi 30.11.05 23:25, insgesamt 1-mal bearbeitet
|
|
Grishnak
      
Beiträge: 221
Windows XP Home
Delphi 7 PE, Delphi 2005 PE
|
Verfasst: 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
      
Beiträge: 552
(D3/D7/D8) Prof.
|
Verfasst: Do 01.12.05 01:13
Verwende mal Double anstatt von Extended, das bringt schon ein paar Prozentchen.
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: 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
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
      
Beiträge: 1284
W98 W2k WXP
Turbo D
|
Verfasst: 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 wieder form7.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)
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; 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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Do 01.12.05 11:09
Kroko 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: |
Kroko 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.
Kroko hat folgendes geschrieben: | (5)
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; BitBlt (canvas.handle,0,0,640,480, B.Canvas.handle,0,0,SRCCOPY); | |
Zeile 18 und 19 kann man besser als
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
      
Beiträge: 552
(D3/D7/D8) Prof.
|
Verfasst: Do 01.12.05 11:52
Kroko 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
      
Beiträge: 98
Win2k prof, WinXP prof, Linux
D6 Prof, BCB4 Std, BCB6 Ent, BDS 2006 Ent
|
Verfasst: 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
      
Beiträge: 1284
W98 W2k WXP
Turbo D
|
Verfasst: Do 01.12.05 12:48
sorry, das in den Zeilen 18/19 habe auch übersehen, Geschwindigkeitsvorteil gibts später, muss jetzt arbeiten 
_________________ Die F1-Taste steht nicht unter Naturschutz und darf somit regelmäßig und oft benutzt werden! oder Wer lesen kann, ist klar im Vorteil!
|
|
|