Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Library: Algorithmen (https://www.delphipraxis.net/28-library-algorithmen/)
-   -   Delphi Mandelbrot-Fraktal über Assembler berechnen (https://www.delphipraxis.net/63318-mandelbrot-fraktal-ueber-assembler-berechnen.html)

Arno-Wien 16. Feb 2006 19:52


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 20:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz