Einzelnen Beitrag anzeigen

Arno-Wien
(Gast)

n/a Beiträge
 
#1

Mandelbrot-Fraktal über Assembler berechnen

  Alt 16. Feb 2006, 19:52
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]
Angehängte Dateien
Dateityp: zip fraktale_139.zip (497,4 KB, 219x aufgerufen)
  Mit Zitat antworten Zitat