Autor Beitrag
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Sa 22.06.13 17:12 
Hallo,
da ich nun einen neuen und ziemlich schnellen Computer habe :D , teste ich alte Programme und fast alle laufen viel schöner und schneller. Leider gilt das für mein Mandelbrotmengen-Programm nur bedingt. Der Geschwindigkeitsgewinn ist unbedeutend.
Woran kann das liegen?

Der Assembler-Teil der Routine, bei dem ich vermute, dass er "bremst", ist nicht von mir. Diesen habe ich vor vielen Jahren einmal "raub"kopiert, woher weiß ich leider nicht mehr. :cry: Deshalb fehlen auch Kommentare.
Ich hoffe, dass es keine Zumutung ist, sich da durch zu kämpfen.
ausblenden volle Höhe Quelltext
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:
       ASM
         FLD     radius
         FLD     xf
         FLD     yf
         FLD     st
         FMUL    st,st
         FLD     st(2)
         FMUL    st,st
         FLD     st(2)
         FLD     st(4)
         XOR     cx,cx
@itloop: INC     cx
         CMP     cx,it
         JE      @noloop
         FMUL
         FADD    st,st
         FADD    st,st(3)
         FLD     st(1)
         FSUB    st,st(3)
         FADD    st,st(5)
         FST     st(3)
         FMUL    st,st
         FSTP    st(2)
         FLD     st
         FMUL    st,st
         FADD    st,st(2)
         FCOM    st(6)
         FSTSW   ax
         FSUB    st,st(2)
         FXCH    st(3)
         AND     ah,1
         JNZ     @itloop
@noloop: MOV     i, cx
         FINIT
      END;

Da dieser Ausschnitt wenig sagt, hänge ich ein Testprogramm an.
Das Aufrufen von application.processmesages kann ich leider nicht weglassen, da ich auch stark vergrößerte Ausschnitte mit einer hohen Iterationszahl berechnen möchte.
Danke für Eure Hilfe.

Beste Grüße
Mathematiker

Rev 1: Mit Zeitmessung und 6 verschiedenen Ausschnitten.
Rev 2: Mit Abbruchmöglichkeit.
Einloggen, um Attachments anzusehen!
_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein


Zuletzt bearbeitet von Mathematiker am So 23.06.13 15:51, insgesamt 2-mal bearbeitet
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: So 23.06.13 11:15 
Hallo,

Zumindest sollte die Geschwindigkeit des Assemblerabschnittes linear mit der Prozessorfrequenz zugelegt haben.
Ich brauche bei 3,2 Ghz AMD 0,387 Sekunden für ein Bild erhöht auf 768x768 = 589824 Bildpunkte
Das sind 46.161.048 Berechnungen = 78,26 Ber/Bildpunkt , 26,8 CPU-Takte/Ber oder 106 Mio Iter/s unter Win7-32.
Soooo lahm ist das ja nicht für 19 innere Asm Befehle und die schleifen drumherum die aber eben um den Faktor 78 reduziert in der Wirkung sind.
Ich habe aber auch eine pf32Bit Bitmat genutzt.Damit gint das setzten der Pixel zeitmäßig völlig unter.
ausblenden volle Höhe Delphi-Quelltext
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:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
unit umandel;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  _farbe = record a,b,g,r:byte; end;

  TForm1 = class(TForm)
    Panel1: TPanel;
    PaintBox1: TPaintBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    pal:array[0..255of _farbe;
    sum : int64;
    T1,T0: TDatetime;
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);

VAR radius,a,b,da,db,xf,yf,
    _x1,_y1,_x2,_y2 : double;
    i,it,xs,ys : word;
    rowrgb : pIntegerarray;
    tempbitmap : tbitmap;
    breite, hoehe:integer;

BEGIN
    breite:=paintbox1.width;
    hoehe:=paintbox1.height;

    tempbitmap:=tbitmap.create;
    tempbitmap.pixelformat:=pf32bit;
    tempbitmap.width:=breite;
    tempbitmap.height:=hoehe;

    it :=500//ein_int(e1);
    _x1:=-2.2;
    _x2:=1.2;
    _y1:=-1.5;
    _y2:=1.5;

    da := (_x2-_x1) / breite;
    db := (_y2-_y1) / hoehe;
    radius := 9;

  b := _y2;
  sum := 0;
  T0 := time;
  FOR ys:=0 TO hoehe-1 DO
  BEGIN
    rowrgb:=tempbitmap.scanline[ys];
    b := b - db;
    a := _x1;
    FOR xs:=0 TO breite-1 DO
    BEGIN
      a := a + da;
      xf:=a;
      yf:=b;
      ASM
         FLD     radius
         FLD     xf
         FLD     yf
         FLD     st
         FMUL    st,st
         FLD     st(2)
         FMUL    st,st
         FLD     st(2)
         FLD     st(4)
         XOR     cx,cx
@itloop: INC     cx
         CMP     cx,it
         JE      @noloop
         FMUL
         FADD    st,st
         FADD    st,st(3)
         FLD     st(1)
         FSUB    st,st(3)
         FADD    st,st(5)
         FST     st(3)
         FMUL    st,st
         FSTP    st(2)
         FLD     st
         FMUL    st,st
         FADD    st,st(2)
         FCOM    st(6)
         FSTSW   ax
         AND     ah,1
         FSUB    st,st(2)
         FXCH    st(3)
         JNZ     @itloop
@noloop: MOV     i, cx
         FINIT
      END;
      inc(sum,i);
      if i>=it then
        i:=0
      else
        i:=i and  255;
//    farbfeld[xs,ys]:=i;     wird im eigentlichen Programm zur Rotation der Farben verwendet

      rowrgb[xs]:=integer(pal[i]);
    END;
  END;
  T1 := time;
  tempbitmap.Canvas.TextOut(10,10,FormatDateTime('HH:NN:SS.ZZZ',T1-T0));
  tempbitmap.Canvas.TextOut(10,30,IntToStr(Sum));
  Paintbox1.canvas.draw(0,0,tempbitmap);
  tempbitmap.free;
END;

procedure TForm1.FormActivate(Sender: TObject);
var i:integer;
begin
    pal[0].r:=0;
    pal[0].g:=0;
    pal[0].b:=0;
    pal[0].a:=0;
    for i:=1 to 255 do
      with pal[i] do
      begin
        a:=0;
        b:=(64+2*i) AND 255;
        g:=(32+4*i) AND 255;
        r:=i;
      end;
end;

end.

Wenn die Farben nicht stimmen muß rgb anders angeordnet werden.

Es gibt im Netz aber auch zahlreiche Verbesserungen.:
Zum Beispiel SSE2
www.codeproject.com/...actals-with-SSE-SSE2
oder FPU bis SSE4.1 in Assembler.
www.mikusite.de/pages/x86.htm dort erreiche ich im FPU-Bench 1433 Mio Iter/s ( 4 Kerne benutzt) ist also nur ;-) 358% schneller für einen einzelne CPU.

Gruß Horst

Für diesen Beitrag haben gedankt: Mathematiker
Mathematiker Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 23.06.13 13:06 
Hallo Horst_H,
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Zumindest sollte die Geschwindigkeit des Assemblerabschnittes linear mit der Prozessorfrequenz zugelegt haben.

Leider nicht, ich glaube aber den wahren Übeltäter gefunden zu haben: das application.processmessages.
Da ich nach einer gewissen Anzahl von berechneten Zeilen processmessages aufrufe, und das wohl viel Zeit benötigt, war der Geschwindigkeitsgewinn kaum zu merken.
Ich habe jetzt in Rev 1 den Aufruf so gesteuert, dass er nach etwa 1 Sekunde erfolgt und schon wird es schneller.
Für eine hohe Anzahl von Iterationen entsteht das Bild nun auch noch schrittweise (und man könnte auch einen Abbruch einbauen), für Bilder mit einem geringen Anteil der eigentlichen Mandelbrotmenge erhält man die Abbildung sofort.

Ich habe zusätzlich noch 5 weitere Abbildungsbereiche eingebaut.
Insbesondere bei den letzten merkt man deutlich, dass 250 oder 500 Iterationen für eine korrekte Darstellung zu wenig sind.

user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
    rowrgb : pIntegerarray;
...
    tempbitmap.pixelformat:=pf32bit;
...
    rowrgb[xs]:=integer(pal[i]);

pIntegerarray kennt Delphi 5 nicht. Deshalb habe ich es nach docwiki.embarcadero....System.PIntegerArray durch
ausblenden Delphi-Quelltext
1:
2:
3:
type
   IntegerArray = array [0..251658239of Integer;
   PIntegerArray = ^IntegerArray;

ersetzt. Dann erhalte ich aber bei
ausblenden Delphi-Quelltext
1:
rowrgb[xs]:=integer(pal[i]);					

einen Übersetzungsfehler.
Aus diesem Grund bin ich noch bei einem 24bit-Bitmap geblieben.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: So 23.06.13 14:34 
Hallo,

ich komme auf 511 ms für die Einstellung im Bild (#2 bei 6000 Iterationen ) .
Aber #1 bei 6000 Iterationen dauert ~3500 ms.Wenn ich mal wieder öfter auf Darstellung klicke, wird die Zeit immer erhöht und dann steht dort 1.4e4 ms -> 14000 ms-> 6 mal gedrückt.
Es ist prächtig anzusehen.
Ich hoffe, Du hast diese Miniprogramme (ca. 3 Kb) von mikusite.de/pages/x86.htm auf Deinem neuem Rechner mal testen können.

Gruß Horst
Mathematiker Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 23.06.13 14:44 
Hallo,
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Ich hoffe, Du hast diese Miniprogramme (ca. 3 Kb) von mikusite.de/pages/x86.htm auf Deinem neuem Rechner mal testen können.

Hätte ich, wenn mein neuer Rechner, besser Win 8, nicht sinngemäß meldet:
"Die Ausführung des Programms wird verhindert, da es den Computer gefährdet!" :nixweiss:

user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich mal wieder öfter auf Darstellung klicke, wird die Zeit immer erhöht und dann steht dort 1.4e4 ms -> 14000 ms-> 6 mal gedrückt.

Ich weiß, das habe ich nicht abgefangen. :autsch:

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: So 23.06.13 15:25 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:

"Die Ausführung des Programms wird verhindert, da es den Computer gefährdet!" :nixweiss:


Entspann dich. Das wird bei allen Anwendungen gezeigt, die kein Publisherzertifikat (sinngemäß) haben. Wenn dir die Quelle der Software also vertrauenswürdig erscheint, kannst du die Software ruhig ausführen (durch Klick auf Details->Trotzdem Ausführen).

Gruß

Für diesen Beitrag haben gedankt: Mathematiker
Mathematiker Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 23.06.13 15:40 
Hallo,
user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:
Entspann dich. Das wird bei allen Anwendungen gezeigt, die kein Publisherzertifikat (sinngemäß) haben.

Danke, wieder 'was gelernt. Ich komme mir vor, wie der blutigste Anfänger. :oops:
Allerdings ergibt sich für mich die Frage:
Wieso meldet Win8 dann bei meinen eigenen Programmen so etwas nicht. Ein solches Zertifikat habe ich doch auch nicht?

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: So 23.06.13 15:45 
Da die Herkunft der Programme dort klar ist, denk' ich mal. Da war ich gerade etwas unpräzise ;)
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: So 23.06.13 16:30 
Soll da womöglich temporär ein Device Treiber installiert werden ? Denn nur dann brauchts ein solches Zertifikat, Standardanwendungen benötigen sowas nicht.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
Mathematiker Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: So 23.06.13 16:41 
Hallo,
user profile iconOlafSt hat folgendes geschrieben Zum zitierten Posting springen:
Soll da womöglich temporär ein Device Treiber installiert werden ?

Keine Ahnung, wahrscheinlich.
Ich habe eines dieser Programme nun doch ausprobiert. Positiv ist, dass es unglaublich schnell ist, negativ aber, dass es die Auflösung meines Bildschirms umgeschaltet hat. Und gerade bei einem Laptop-Bildschirm macht sich das nicht so gut. :motz:

Nebenbei habe ich in Revision 2 einen möglichen Zeichenabbruch eingebaut.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Fiete
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 601
Erhaltene Danke: 339

W7
Delphi 6 pro
BeitragVerfasst: Mo 24.06.13 12:03 
Moin Mathematiker,
habe in meinem Archiv noch eine Assemblerroutine von 1987 gefunden.
ausblenden volle Höhe Delphi-Quelltext
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:
//  Mandelbrot - Iteration nach Werner Durandi (c't 3/87)

 procedure TMandel.AsmIteration(XC,YC:Extended;Max:Integer;var K:Integer);
  var Vier:Extended;
  BEGIN
   Vier:=4.0;
         ASM
         MOV ECX,Max
         XOR EBX,EBX           // K:=0
         FINIT                 // Stapelzeiger auf R0
         FLD XC                // XC (R7)
         FLD YC                // YC (R6)
         FLD VIER              // 4.0 --> R5
         FLDZ                  // X  (R4):=0
         FLDZ                  // Y2 (R3):=0                
         FLDZ                  // X2 (R2):=0                
         FLDZ                  // Y  (R1):=0      ST0       
   @ITER:FMUL ST,ST(3)         // Y:=Y*X
         FADD ST,ST(0)         // Y:=2*Y
         FADD ST,ST(5)         // Y:=Y+YC                   
         FINCSTP               // auf R2(X)                 
         FSUB ST,ST(1)         // X:=X2-Y2
         FADD ST,ST(5)         // X:=X+XC
         FST ST(2)             // X --> R4                  
         FMUL ST,ST(0)         // X2(R2):=SQR(X)            
         FST ST(6)             // X2 --> R0 (für X2+Y2>4.0)
         FDECSTP               // ST auf R1                 
         FST ST(2)             // Y2:=Y                     
         FMUL ST(2),ST         // SQR(Y) --> Y2(R3)         
         FDECSTP               // ST auf R0                 
         FADD ST,ST(3)         // X2+Y2                     
         FCOMP ST(5)           // IF X2+Y2>4.0(R5), ST danach auf R1
         FSTSW AX              // Status-Word in AX speichern
         SAHF                  // AH --> FLAGS
         JA @ENDE              // größer 4.0 --> Ende
         INC EBX               // INC(K)
         CMP EBX,ECX           // ZÄHLER=Max ?
         JB @ITER
   @ENDE:MOV EDI,K
         MOV [EDI],EBX         // K als Ergebnis
         FINIT                 // alle 80387-Register leeren
         END
  END;

Im Anhang das ganze Programm.
Die Befehle sind für einen 8087(FPU), in zwischen wird es für die aktuellen Prozessoren wohl etwas anderes geben.
Gruß Fiete
Einloggen, um Attachments anzusehen!
_________________
Fietes Gesetz: use your brain (THINK)

Für diesen Beitrag haben gedankt: glotzer, Mathematiker