Entwickler-Ecke

Sonstiges (Delphi) - Rechenpower von Delphi (mathematisch).


Hochhaus - Di 12.06.12 16:21
Titel: Rechenpower von Delphi (mathematisch).
Hallo allerseits !

ich hatte die Idee, die mathematische Performance von Delphi zu testen. Und siehe da: Delphi 6 Professional ist bei aufwändigen Mathe-Problemen deutlich schneller, als der Code von Delphi XE2. Ich stellte einen Performance-Verlust von ca. einem Faktor 1.4 fest. Konkret habe ich die Quadratwurzel von 2 gezogen. Und siehe da, Delphi 6 Professional brauchte dafür auf einem Core I7-Prozessor 40 msec., aber Delphi XE2 ca. 56 msec.

Dies ist an und für sich keine Tragödie, aber doch unschön.- Was ist Eure Meinung ? Habt Ihr dieselbe Erfahrung auch gemacht ?

Gruss,


Hochhaus


Gausi - Di 12.06.12 16:28

Liegt das wirklich an den Berechnungen, oder z.B. an der Ausgabe als String?


Yogu - Di 12.06.12 16:30

Hallo,

50 Millisekunden sind etwas wenig für einen Performance-Test, ich würde die Anzahl der Durchläufe erhöhen, bis es ein paar Sekunden braucht. Und hast du die Programme auch außerhalb des Debuggers gestartet, also die generierte Exe-Datei selbst?

Wenn wirklich ein Unterschied besteht, müsste der im Assembler-Code zu finden sein. In Delphi kannst du das CPU-Fenster aufrufen, dann einen Haltepunkt im Code setzten, damit du siehst, wo der interessante Code ist. Kann aber sein, dass der dann noch nicht vollständig optimiert ist.

Grüße,
Yogu


Gammatester - Di 12.06.12 16:37

50 ms? Und das soll auch noch wenig sein. Auf meinen Celereon 500Mhz brauche ich für 1Mio Berechnungen gerade mal 0.26s, also pro sqrt 0.26 µs!


Hochhaus - Di 12.06.12 16:39

user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,

50 Millisekunden sind etwas wenig für einen Performance-Test, ich würde die Anzahl der Durchläufe erhöhen, bis es ein paar Sekunden braucht. Und hast du die Programme auch außerhalb des Debuggers gestartet, also die generierte Exe-Datei selbst?


Grüße,
Yogu


Ich habe die EXE-Dateien (ohne Debugger) direkt aufgerufen. Selbstverständlich habe ich die Stellenzahl auch deutlich erhöht, dann ist das Verhältnis 4 sec. zu 5.6 sec.


Hochhaus


jaenicke - Di 12.06.12 16:44

Es kommt auch darauf an die Datentypen günstig zu wählen, also nicht sowas wie Single oder sogar Extended.

Wie sieht der Code denn aus? Wie wäre es mit einem Demoprojekt? ;-)


Martok - Di 12.06.12 16:46


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:
program Project1;
{$apptype console}
uses
  Windows;
const
  COUNT = 1000*1000*1000;
var
  f,t1,t2: Int64;
  ttttt: Double;
  i: integer;
begin
  QueryPerformanceFrequency(f);
  QueryPerformanceCounter(t1);
  for i:= 0 to COUNT-1 do begin
  end;
  QueryPerformanceCounter(t2);
  WriteLn('Calibrate: ',((t2-t1)/f)/COUNT * 1000000,'ns');

  QueryPerformanceCounter(t1);
  for i:= 0 to COUNT-1 do begin
    ttttt:= sqrt(2);
  end;
  QueryPerformanceCounter(t2);
  WriteLn('Run: ',((t2-t1)/f)/COUNT * 1000000,'ns');
  ReadLn;
end.


stdout
1:
2:
Calibrate:  4.51228689679834E-0003ns
Run:  1.96267299335530E-0002ns


user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
Wenn wirklich ein Unterschied besteht, müsste der im Assembler-Code zu finden sein. In Delphi kannst du das CPU-Fenster aufrufen, dann einen Haltepunkt im Code setzten, damit du siehst, wo der interessante Code ist.
Viel zu optimieren gibts da nicht.

Quelltext
1:
2:
3:
4:
5:
Project1.dpr.15: ttttt:= sqrt(2);
004043C7 DB2D60444000     fld tbyte ptr [$00404460]
004043CD D9FA             fsqrt 
004043CF DD1D7C664000     fstp qword ptr [ttttt]
004043D5 9B               wait

Außer natürlich direkt FLD auf eine Konstante mit der 1.4142135623730952 ;)


Hochhaus - Di 12.06.12 16:53

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Es kommt auch darauf an die Datentypen günstig zu wählen, also nicht sowas wie Single oder sogar Extended.

Wie sieht der Code denn aus? Wie wäre es mit einem Demoprojekt? ;-)


Ist als Zip-Datei in der Beilage.

Hochhaus


Martok - Di 12.06.12 17:08

Achsooo, Arbitrary Precision (naja, mehr oder weniger fixed) ;)

Solange da ein ProcessMessages drin ist, würde ich dem nicht weiter trauen als ich meinen Computer werfen würde.


jaenicke - Di 12.06.12 17:09

XE und XE2 (ich weiß nicht welche noch) binden den Sqrt Befehl soweit ich mich erinnere nicht inline ein. Das könnte der Grund sein, dass es etwas langsamer ist, wenn es denn tatsächlich an dieser einen Funktion liegt. Da da noch ziemlich viel Kuddelmuddel drum ist in dem Projekt, taugt das ja eh nicht zur Geschwindigkeitsmessung (habs nur kurz überflogen, genauer kann ich heute Abend schauen...).


Blup - Di 12.06.12 17:13

Delphi 2007

Calibrate: 3.52052285974893E-0004ns
Run: 3.53167198624406E-0002ns

Quelltext
1:
2:
3:
4:
5:
6:
Project1.dpr.22: ttttt:= sqrt(2);
0040515E 6800400000       push $00004000
00405163 6800000080       push $80000000
00405168 6A00             push $00
0040516A E821DCFFFF       call Sqrt
0040516F DDD8             fstp st(0)


jaenicke - Di 12.06.12 17:14

Dann ist es da ja auch schon ohne inline Sqrt. Lustig ist übrigens wie der Befehl bei XE aussieht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function Sqrt(const X: Extended): Extended;
{$IFDEF CPU386}
asm
        FLD     X
        FSQRT
        FWAIT
end;
{$ELSE}
begin
  Result := 0;
end;
{$ENDIF}
:lol:

// EDIT:
Ach ja: Inline ist es nicht, weil es eine Assemblerfunktion ist. Sowas lässt sich in Delphi nicht inline einbinden.


Martok - Di 12.06.12 17:39

In D7 ist das nicht mal eine Pseudofunktion in System.pas, sondern anscheinend direkt Magic.
Und dass Delphi sich beim inlinen doof hat stört mich auch schon länger... Mal sehen, nächstes Jahr um die Zeit gibts vielleicht ein bis dahin brauchbares FPC-Kompatibles LLVM-Frontend [http://code.google.com/p/llvm-pascal]. Der würde dann die Schleife gleich komplett rausoptimieren ;)


Hochhaus - Di 12.06.12 19:05

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
XE und XE2 (ich weiß nicht welche noch) binden den Sqrt Befehl soweit ich mich erinnere nicht inline ein. Das könnte der Grund sein, dass es etwas langsamer ist, wenn es denn tatsächlich an dieser einen Funktion liegt. Da da noch ziemlich viel Kuddelmuddel drum ist in dem Projekt, taugt das ja eh nicht zur Geschwindigkeitsmessung (habs nur kurz überflogen, genauer kann ich heute Abend schauen...).


Mein einfaches Primzahlenprogramm ist nur ca. 10 % langsamer unter Delphi XE2, verglichen mit Delphi 6. Es scheint sehr stark von den verwendeten Funktionen abzuhängen ...


Hochhaus