Was macht dieser Assembler-Code?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
sstvmaster
Beiträge: 576
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Was macht dieser Assembler-Code?

Beitrag von sstvmaster »

Hi,

hier mein Test mit Windows 10 (i3-9100):
Pascal = 7750 ms
Assembler = 7266 ms
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Was macht dieser Assembler-Code?

Beitrag von theo »

Ally hat geschrieben:
Di 15. Nov 2022, 12:40
Interessant.
Ich habe den Code etwas abgeändert, damit das Resultat auch verwendet wird und nichts wegoptimiert wird.
Dabei komme ich auf folgende Resultate
Func: 8658ms 192046823006208
Asm: 7721ms 192046823006208
MinMax: 5056ms 192046823006208
Lazarus 2.3.0 (rev main-2_3-2199-g898f4009c0) FPC 3.2.2 x86_64-linux-gtk2

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  a, b, Start, Stopp: Integer;
  c:Int64;
begin
  c:=0;
  Start := GetTickCount64;
  for a := 0 to $FFFF do
    for b := 0 to $FFFF do
      c:=c+CalcPascal(a, b);
  Stopp := GetTickCount64;
  Memo1.Lines.Add('Func: '+IntToStr(Stopp - Start)+'ms '+c.ToString);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  a, b, Start, Stopp: Integer;
  c:Int64;
begin
  c:=0;
  Start := GetTickCount64;
  for a := 0 to $FFFF do
    for b := 0 to $FFFF do
     c:=c+CalcAssembler(a, b);
  Stopp := GetTickCount64;
  Memo1.Lines.Add('Asm: '+IntToStr(Stopp - Start)+'ms '+c.ToString);
end;

procedure TForm1.Button3Click(Sender: TObject);
  var
    a, b, Start, Stopp: Integer;
    c:Int64;
  begin
    c:=0;
    Start := GetTickCount64;
    for a := 0 to $FFFF do
      for b := 0 to $FFFF do
       c:=c+Min(Max(a+b-$3FFF,0),$FFFF);
    Stopp := GetTickCount64;
    Memo1.Lines.Add('MinMax: '+IntToStr(Stopp - Start)+'ms '+c.ToString);
  end;   
P.S. Syntaktisch geht es übrigens noch übersichtlicher:

Code: Alles auswählen

k:=EnsureRange(i+j-$40,0,$FF);

Benutzeravatar
Ally
Beiträge: 263
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Was macht dieser Assembler-Code?

Beitrag von Ally »

Hallo theo,

es macht einen ordentlichen Unterschied ob man die Function CalcPascal aufruft oder den Functionscode direkt ausführt.
Da die Function in meinem Programm öfter aufgerufen wird ist das eher weniger schön.
Deine Idee mit EnsureRange ist der "Gamechanger", aufrufbar in einer Zeile und nur minimal langsamer.
Die Würfel sind gefallen. Danke für den Hinweis.

Gruß Roland

siro
Beiträge: 732
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Was macht dieser Assembler-Code?

Beitrag von siro »

Intel Celeron J4105 CPU 1.50GHz

Code: Alles auswählen

Pascal                   : 26344ms  
Assembler                : 26828ms
MinMax als Unterprogramm : 24844ms
MinMax direkt als Code   : 15969ms
Einen Hauptanteil der Zeit wird also vom Unterprogramm Aufruf benötigt.
es sei denn ich deklariere die Funktion als INLINE
dann braucht MinMax tatsächlich nur 12469ms,
das wundert mich jetzt doch :shock:

ja, ich weis mein Rechner ist langsam.... :P :lol:
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Was macht dieser Assembler-Code?

Beitrag von theo »

Ally hat geschrieben:
Di 15. Nov 2022, 15:56
es macht einen ordentlichen Unterschied ob man die Function CalcPascal aufruft oder den Functionscode direkt ausführt.
Fairerweise muss man sagen, dass Math.Max etc. syntaktisch auch Funktionsaufrufe sind.
Diese sind aber mit dem "inline" modifier versehen.

Mach mal so und staune! :wink:

Code: Alles auswählen

function CalcPascal(a, b: Integer): Integer; inline;
begin
  a := a + b - $3FFF;
  if a < 0 then
    Exit(0);
  if a > $FFFF then
    Exit($FFFF);
  Result := a;
end;     
https://wiki.freepascal.org/Inline

Edit: @siro: Genau!

siro
Beiträge: 732
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: Was macht dieser Assembler-Code?

Beitrag von siro »

AHA.... :shock:
jetzt nur noch 15515ms als Inline von vorher 26344ms
Da kann man doch so Einiges herausholen,
danke Theo
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
Ally
Beiträge: 263
Registriert: Do 11. Jun 2009, 09:25
OS, Lazarus, FPC: Win und Lazarus Stable release
CPU-Target: x64

Re: Was macht dieser Assembler-Code?

Beitrag von Ally »

Hallo theo,
Mach mal so und staune!
Ja hatte ich, nach siro's Stichwort, gerade ausprobiert.
Letztendlich bleibe ich aber bei EnsureRange. Man muss ja nichts einbauen was schon vorhanden ist.
Ok, man muss Math einbinden, was sich aber im konkreten Fall nicht auf die Programmgröße auswirkt.

Gruß Roland

PascalDragon
Beiträge: 830
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Was macht dieser Assembler-Code?

Beitrag von PascalDragon »

fliegermichl hat geschrieben:
Di 15. Nov 2022, 09:36
Das kompiliert natürlich wieder nicht auf 32 Bit Targets.
Hier geht es um Assembler Code, der ist platformspezifisch. Dann machst eben folgendes draus:

Code: Alles auswählen

{$if defined(cpux86_64)}
{ hier der x86_64 Assembly Code }
{$elseif defined(cpu386)}
{ hier der i386 Assembly Code }
{$else}
{ hier das Pascal Only Fallback }
{$endif}
Damit kann man auch leicht Übersetzungen für andere Platformen hinzufügen.

(In diesem konkreten Beispiel geht es allerdings wie theo gezeigt hat die beiden x86 Plattformen mit einem Code abzudecken, aber das ist nicht die allgemeine Lösung und es gibt auch noch andere Plattformen als die x86 Familie)
FPC Compiler Entwickler

Antworten