AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Library: Algorithmen Delphi Mandelbrot-Fraktal über Assembler berechnen
Thema durchsuchen
Ansicht
Themen-Optionen

Mandelbrot-Fraktal über Assembler berechnen

Ein Thema von Arno-Wien · begonnen am 16. Feb 2006
Antwort Antwort
Arno-Wien
(Gast)

n/a Beiträge
 
#1

Mandelbrot-Fraktal über Assembler berechnen

  Alt 16. Feb 2006, 20: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
Antwort Antwort

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:57 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