Hallo,
besonders bei 32-Bit bekommt man die geringe Zahl an Registern zu spüren.Das auslagern in kleine Funktionen bringt erheblich was und es sollte auch vergleichbarer werden, egal wo man die Funktion im Quelltext benutzt.
Code: Alles auswählen
program p;
uses
sysutils;
const
IMAX = 250000000;
var
x: double;
QueryLos, QueryHalt : Int64;
function GetPiAdrian:double;
var
x,n : double;
i : NativeInt;
begin
n:=1;
x := 0;
for i:=2*Imax-1 downto 0 do
begin
x := x + (1/n);
// leicht geändert und einen Vergleich gespart, denn n= 0 kommt nicht vor
if n>0 then
n:= -(n+2)
else
n:= -(n-2);
end;
GetPiAdrian := x;
end;
function GetPiNativeInt:double;
var
x : double;
n : NativeInt;
i : NativeInt;
begin
n:=1;
x := 0;
for i:=1 to IMAX do
begin
x:=x+(1/n);
inc(n, 2);
x:=x-(1/n);
inc(n, 2);
end;
GetPiNativeInt := x;
end;
function GetPiLongInt:double;
var
x : double;
n : LongInt;
i : NativeInt;
begin
n:=1;
x := 0;
for i:=1 to IMAX do
begin
x:=x+(1/n);
inc(n, 2);
x:=x-(1/n);
inc(n, 2);
end;
GetPiLongInt := x;
end;
function GetPiDouble:double;
var
x,n : double;
i : NativeInt;
begin
n:=1;
x := 0;
for i:=1 to IMAX do
begin
x:=x+(1.0/n);
n:=n+2;
x:=x-(1.0/n);
n:=n+2;
end;
GetPiDouble:= x;
end;
begin
WriteLn('Adrian / double');
QueryLos := GetTickCount64;
x := GetPiAdrian;
QueryHalt := GetTickCount64;
writeln(QueryHalt-QueryLos); writeln(x*4.0-pi);WriteLn;
WriteLn('Horst_h / NativeUInt');
QueryLos := GetTickCount64;
x := GetPiNativeInt;
QueryHalt := GetTickCount64;
writeln(QueryHalt-QueryLos);writeln(x*4.0-pi);WriteLn;
WriteLn('Horst_h / integer');
QueryLos := GetTickCount64;
x := GetPiLongInt;
QueryHalt := GetTickCount64;
writeln(QueryHalt-QueryLos);writeln(x*4.0-pi);WriteLn;
WriteLn('Horst_h / double');
QueryLos := GetTickCount64;
x:= GetPiDouble;
QueryHalt := GetTickCount64;
writeln(QueryHalt-QueryLos);writeln(x*4.0-pi);WriteLn;
WriteLn('ENTER druecken zum Beenden...');
ReadLn;
end.
Linux64
Ryzen 5 1600 @ 3.2 Ghz ( Turbo? aus )
32-Bit Kompilat fpc -O1 -al -Xs "%f" // Benutzt die FPU und schreibt sichert ständig die Daten auf den Stack.
Code: Alles auswählen
Adrian / double
2727
-2.00038753378657674364E-0009
Horst_h / NativeUInt
2318
-2.00038753378657674364E-0009
Horst_h / integer
2318
-2.00038753378657674364E-0009
Horst_h / double
2407
-2.00038753378657674364E-0009
ENTER druecken zum Beenden...
64-Bit Kompilat
/usr/lib/fpc/3.0.4/ppcx64 -O1 -al -Xs "%f"
Code: Alles auswählen
Adrian / double
1916
-2.00053541549345681450E-0009
Horst_h / NativeUInt
1662
-2.00053541549345681450E-0009
Horst_h / integer
1659
-2.00053541549345681450E-0009
Horst_h / double
1707
-2.00053541549345681450E-0009
ENTER druecken zum Beenden...
Jetzt die Optimierung hochgeschraubt, die bei 32-Bit fast nichts brachte.
/usr/lib/fpc/3.0.4/ppcx64 -O3 -al -Xs "%f"
Code: Alles auswählen
Adrian / double
657
-2.00053541549345681450E-0009
Horst_h / NativeUInt
615
-2.00053541549345681450E-0009
Horst_h / integer
616
-2.00053541549345681450E-0009
Horst_h / double
612
-2.00053541549345681450E-0009
ENTER druecken zum Beenden...
Man sieht, dass die Berechnung mit der FPU ( 32-Bit ) leicht andere Zahlen als mit SSE ( 64-Bit ) liefert.
Gruß Horst
EDIT:
es 500e6 Berechnungen.
Takte pro Berechnugen = Zeit/AnzahlBerechnungen * CPU-Takte
612 ms/500e6*3,2e6 Takte/ms = 3,917 Takte/Berechnung selbst bei Turbo mit 3,6 Ghz sind es nur 4,4 Takte.