It shows with useless code like simple nested for .. to loops, but also
with some more useful code like the attached RSA_Angriff from the C'T
magazine.
My results are with:
fpc -Sd -OG3rp3 -XX RSA_Angriff_D5.dpr
5266 ms
with:
fpc -Sd -XX RSA_Angriff_D5.dpr
4844 ms
The unoptimized code is faster than the optimized code.
(BTW. I choosed an example where the Delphi compiler is really worse ;-)
: 65953 ms)
Same picture with the whet.pas (whether or not the whetstone benchmark
is useful) from your source distribution.
With optimization on: 7393.72 MIPS
With optimization off: 8368.20 MIPS
cheers,
Adrian.
Florian Klaempfl schrieb:
Adrian Veith wrote:
Hi,
I am newbie with fpc (but not with pascal, which I use more than 20y now).
We have lot of existing delphi code, which some of it, I want to port to
new platforms - and fpc looks like the right tool for it. But I am
concerned about the speed. I did some basic benchmarks and it seems,
that the optimizers has no effect in the 2.0 compiler (or the code even
get's slower).
This shouldn't be the case in general, can you give examples or post the
benchmark? And don't try with useless code, we don't care about optimziations
which test only useless code which never happens in real programs.
With the 1.9.8 compiler, the same code executes 4 times quicker - what
happend (or what do I wrong) ?
For optimizing I use the -OG3rp3 switch - is it still valid ?
Thanks,
Adrian.
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
program RSA_Angriff_D5;
(* Benchmarkversion testet Laufzeitverhalten primitiver Datentypen.
* - Konsolenprogramm
* - Auswahl zwischen bitorientierter Routine mit aufwändiger Rekursion
DoPrim2()
* und BruteForce-Routine DoPrimBruteForce() schlicht durch Auskommentieren
in main()
* - zu zerlegende Zahl als BigNumber definiert.
*
* Anmerkung: DoPrimBruteForce() findet auch kleine Primfaktoren,
* DoPrim2() ignoriert diese, da RSA-Paare immer große Primfaktoren
haben
* (thats a bug, but also a feature)
*)
{$APPTYPE CONSOLE}
uses
SysUtils,
Windows;
const
BigNumber: int64 = 34571237124234713;
procedure DoPrimBruteForce(NumberToCrunch: int64);
var i, j, UBound: int64; UBoundC: Comp;
begin
i := 3;
// ohne den Umweg über eine Gleitkommazahl
// schafft Delphi das nicht
UBoundC := NumberToCrunch;
UBound := Round(Sqrt(UBoundC));
while i < UBound do
begin
if NumberToCrunch mod i = 0 then
begin
j := NumberToCrunch div i;
Writeln(i, ' * ', j, ' = ', j * i);
end;
Inc(i,2);
end;
end;
procedure DoPrim2(NumberToCrunch: int64);
var UBound, z: int64;
procedure Prim(
n: Integer; // Bitmaske bis m-te Stelle, also 2^m - 1
m: Integer; // Stelle (Zweierpotenz)
i, // 1. Kandidat für Primzahl
j, // 2. Kandidat für Primzahl
res: int64); // bisher auf m Stellen synthetisiertes Produkt
var
product: int64;
z0: int64;
m1, n1: Integer;
im, jm: int64;
begin
product := i * j; // Überlauf? dann Ende der Rekursion
// Rekursion bricht ab, wenn
// - 1. Kandidat größer als Wurzel der Zahl
// - Produkt zu groß
// - m wegen überlauf negativ wird
if (i < UBound) and (product < z) and (m > 0) then
begin
z0 := z and n; // Ausfiltern der relevanten
Stellen
m1 := m shl 1; // nächste Stelle
n1 := n or m1; // Bitmaske erweitern
// Tiefensuche rekursiv!
// Es gibt vier mögliche Fälle, je zwei pro Kandidat
// zwei davon gehen in die Rekursion
// relevant sind nur m Stellen
if (res and n) = z0 // +0, +0 (i, j
unverändert)
then Prim(n1, m1, i, j, res);
im := i or m; // m-tes Bit der Kandidaten
setzen
jm := j or m;
// Testen ob die letzten m Stellen des Kandidatenprodukts stimmen
res := im * j;
if (res and n) = z0 // +1, +0 (m-tes Bit von i gesetzt)
then Prim(n1, m1, im, j, res);
res := jm * i; // +0, +1 (m-tes Bit von j gesetzt)
if (res and n) = z0
then Prim(n1, m1, i, jm, res);
res := im * jm; // +1, +1 (m-tes Bit von i,j gesetzt)
if (res and n) = z0
then Prim(n1, m1, im, jm, res);
end else
begin // Rekursion bricht ab. Stimmt das Produkt etwa?
if (i < UBound) and (product = z)
then Writeln(i, ' * ', j, ' = ', j * i);
end;
end; // Prim
var UBoundC: Comp;
begin
z := NumberToCrunch;
// Wurzelkriterium: ohne den Umweg über eine Gleitkommazahl
// schafft Delphi das nicht
UBoundC := NumberToCrunch;
UBound := Round(Sqrt(UBoundC));
Prim(3, 2, 1, 1, 1); // Start der Rekursion
end; // DoPrim2
var STime: Cardinal;
begin
Writeln('Delphi: Zerlege ',BigNumber);
STime := GetTickCount;
if (ParamCount = 0) or (AnsiUpperCase(ParamStr(1)) <> '-R') then
begin
Writeln('Brute Force (Aufruf mit -R = rekursives Verfahren)');
DoPrimBruteForce(BigNumber);
end else
begin
Writeln('Rekursiver Ansatz (Aufruf ohne -R = Brute Force)');
DoPrim2(BigNumber);
end;
STime := GetTickCount-STime;
Writeln('Dauer (msec): ', STime);
Write('Weiter mit ENTER...');
Readln;
end.
_______________________________________________
fpc-pascal maillist - fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal