![]() |
Mandelbrot-Fraktal über Assembler berechnen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mich gefreut, bei meinem Fraktaleprogramm durch Assemblerroutinen bis zu 75%
Zeitersparnis zu erreichen. Hier die procedure: (in frak_un1) Den ursprünglichen Code habe ich in der Repeat-Schleife in Klammern stehenlassen. Man kann leicht die alte Version probieren. Für mich überraschend war, dass ich den Stack vor der Schleife laden kann, in der Schleife die Werte im Stack halte und nachher erst den Stack poppe. Die Schleife wird u.U. bis zu über 500 000 mal durchlaufen und da wird der Vorteil erst sichtbar. Siehe die zwei mitgelieferten Bilder, die denselben Ausschnitt zeigen. Vorher entzippen Compiler: Optmization: on Record firld alignment: on Extended syntax: on sonst: off Folgender Code beinhaltet den Wesentlichen Teil der Berechnung. Für den gesamten Algorithmus bitte die ZIP-Datei entpacken.
Delphi-Quellcode:
procedure apf_beliebiger_ausschnitt;
var m, n, i: longint; p: PByteArray; zwei, x, y, x_k, x1_k, y_k, y2wert, xqu, yqu, summe, deltax, deltay: extended; procedure laden; asm //ST(0) ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7) fld x_k; //x_k fld y_k; //y_k x_k fld xqu; //xqu y_k x_k fld yqu; //yqu xqu y_k x_k fld y; //y yqu xqu y_k x_k fld x; //x y yqu xqu y_k x_k end; procedure rechnen; asm //ST(0) ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7) fmulp; //x*y yqu xqu y_k x_k fadd ST(0),ST(0) //2*x*y yqu xqu y_k x_k fsub ST(0),ST(3) //y(neu) yqu xqu y_k x_k fxch ST(2) //xqu yqu y y_k x_k fsubrp //xqu-yqu y y_k x_k fsub ST(0),ST(3) //x(neu) y y_k x_k fld ST(0) //x x y y_k x_k fmul ST(0),ST(1) //xqu x y y_k x_k fld ST(1) //y xqu x y y_k x_k fmul ST(0),ST(3) //yqu xqu x y y_k x_k fld ST(1) //xqu yqu xqu x y y_k x_k fadd ST(0),ST(1) //xqu+yqu yqu xqu x y y_k x_k fstp summe //yqu xqu x y y_k x_k fxch ST(1) //xqu yqu x y y_k x_k fxch ST(3) //y yqu x xqu y_k x_k fxch ST(1) //yqu y x xqu y_k x_k fxch ST(2) //x y yqu xqu y_k x_k end; procedure poppen; asm fstp x // nur Stack freigeben fstp y fstp yqu fstp xqu fstp y_k fstp x_k end; begin ausschnitt_check := true; deltax := (c_reel2 - c_reel1)/639; deltay := (c_imag2 - c_imag1)/479; y_k := c_imag1 - deltay; zwei := 2.0; m := 0; repeat p := a_bild.ScanLine[m]; y_k := y_k + deltay; x_k := c_reel1 - deltax; for n:=0 to 639 do begin x1_k := x_k + deltax; x_k := x1_k; x := 0.0; y := 0.0; xqu := 0.0; yqu := 0.0; color := 0; laden; repeat { y:=zwei*x*y-y_k; x:=xqu-yqu-x_k; xqu:=x*x; yqu:=y*y; summe:=xqu+yqu; } rechnen; inc(color); until (summe > maxsum) or (color = colormax); poppen; 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 = 840) or Ende; daten_aktualisieren(werte_apf_alt); BitBlt(bild_apf.canvas.handle, 0, 0, 640, 480, a_bild.canvas.handle, 0, 0, SRCCOPY); end; Arno [edit=Chakotay1308]Code-Style angepasst und Hinweise angefügt. Mfg, Chakotay1308[/edit] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:05 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