Sinus gähnend langsam unter Linux

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Antworten
Mathias
Beiträge: 7368
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Sinus gähnend langsam unter Linux

Beitrag von Mathias »

Ich habe folgendes Testprogramm gemacht, dabei habe ich festgestellt, das sin unter linux fast den Faktor 10 langsamer läuft als unter Windows(wine)
Verwendet man das sin von libm, läuft es auf beiden OS gleich schnell.
Wen es mit wine langsamer wäre würde ich es noch begreifen.

Code: Alles auswählen

program project1;

uses
  SysUtils;

var
  StartTime, FPCTime, CTime: TDateTime;
  r: Double;
  i, y: Int64;

  const
  {$IFDEF MSWINDOWS}
  clib_math = 'msvcrt.dll';
  {$ELSE}
  clib_math = 'm';
  {$ENDIF}

function c_sin(x: Double): Double; cdecl; external clib_math name 'sin';

begin
  WriteLn('Start FPC Sin...');
  StartTime := Now;

  r := 1.0;
  for y := 0 to 1000 do    begin
  Write('.');
  for i := 0 to 1000000 do  begin
      r := cos(r * i);
    end;
  end;
  WriteLn('Ergebnis als Test r: ', r:4:2);
  FPCTime:=Now - StartTime;

  WriteLn('Start libm Sin...');
  StartTime := Now;

  r := 1.0;
  for y := 0 to 1000 do    begin
  Write('.');
  for i := 0 to 1000000 do  begin
      r := c_sin(r * i);
    end;
  end;
  CTime:=Now - StartTime;
  WriteLn('Ergebnis als Test r: ', r:4:2);
  WriteLn(#10#10);
  Writeln('Plattform: ', {$I %FPCTARGETOS%});
  WriteLn('Zeit FPC:  ', FormatDateTime('ss.zzz', FPCTime), 's');
  WriteLn('Zeit libm: ', FormatDateTime('ss.zzz', CTime), 's');
end.
Die Auswertungen, man beachte das 18s bei Linux.

Code: Alles auswählen

Plattform: Linux
Zeit FPC:  18.431s
Zeit libm: 02.431s

Plattform: Win64
Zeit FPC:  02.035s
Zeit libm: 02.062s
Mit Lazarus sehe ich grün
Mit Java, Python und C++ sehe ich rot

wp_xyz
Beiträge: 5507
Registriert: Fr 8. Apr 2011, 09:01

Re: Sinus gähnend langsam unter Linux

Beitrag von wp_xyz »

Warum hast du denn ein "Write()" in der Zeitmess-Schleife, wenn du am sin interessiert bist?

Mathias
Beiträge: 7368
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Sinus gähnend langsam unter Linux

Beitrag von Mathias »

wp_xyz hat geschrieben: Fr 9. Okt 2026, 18:42 Warum hast du denn ein "Write()" in der Zeitmess-Schleife, wenn du am sin interessiert bist?
Nach jedem 1mio Sinus ein Write das tut sicher nicht weh. Und wen es weh täte, würde es die anderen 3 Messungen auch ausbremsen.
Mit Lazarus sehe ich grün
Mit Java, Python und C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7457
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Sinus gähnend langsam unter Linux

Beitrag von af0815 »

... wer sinnerfassend lesen kann ist im Vorteil ...

gelöscht deswegen

Edit:
Ist die Funktion sincos aus der Unit math schneller ? Und einmal verwendest du cos und einmal sin oben im Code. Abhängig von der CPU kann das dann über fsincos direkt auf der CPU laufen. (ist auch in der Unit math so)

https://tizee.github.io/x86_ref_book_we ... incos.html

bei der normalen sin und cos verschwindet das im fpc dschungel (function Sin(d : ValReal) : ValReal;[internproc:fpc_in_sin_real]; ) und ist somit für mich nicht nachvollziehbar.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Warf
Beiträge: 2334
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Sinus gähnend langsam unter Linux

Beitrag von Warf »

Hast du mal ins generierte assembly geschaut? Weil eigentlich sind die trigonometrischen Funktionen so definiert das wenn die platform sie bereit stellt diese einfach auf die entsprechenden FPU Instruktionen der CPU reduziert.

Wenn der unterschied so krass ist würde ich von ausgehen das irgendwie fpc dies ni hat tut und stattdessen sie fallback Implementierung nutzt

Mathias
Beiträge: 7368
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Sinus gähnend langsam unter Linux

Beitrag von Mathias »

Hast du mal ins generierte assembly geschaut?
Nein habe ich nicht, aber ich konnte eine Assembler Datei bauen.
Dateianhänge
project1.s.zip
(2.7 KiB) 24-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java, Python und C++ sehe ich rot

PascalDragon
Beiträge: 1057
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: Sinus gähnend langsam unter Linux

Beitrag von PascalDragon »

Mathias hat geschrieben: Fr 9. Okt 2026, 17:20 Die Auswertungen, man beachte das 18s bei Linux.

Code: Alles auswählen

Plattform: Linux
Zeit FPC:  18.431s
Zeit libm: 02.431s

Plattform: Win64
Zeit FPC:  02.035s
Zeit libm: 02.062s
Bei Linux kann ich mir vorstellen, dass durch die Verwendung der X87 80-bit Floating Point fcos bzw. fsin Instruktion die Sache langsamer ist als das was auch immer libm verwendet.

Unter Windows ist es jedoch komisch, da dort eine Software Implementierung aus Pascal Code verwendet wird und ich eigentlich erwarte, dass es langsamer ist.

Und zumindest bei mir unter Windows 64-bit ist die FPC Variante tatsächlich signifikant langsamer, während sie unter 32-bit etwa gleich schnell ist. Unter WSL-2 ist die FPC Variante ebenfalls langsamer, das könnte aber an der Emulation durch WSL-2 liegen (ich habe grad leider keine WSL-1 Variante laufen, die das ohne Emulation machen würde).

Code: Alles auswählen

Plattform: Win64
Zeit FPC:  00.55.075s
Zeit libm: 00.07.886s

Plattform: Win32
Zeit FPC:  00.44.808s
Zeit libm: 00.55.883s

Plattform: Linux
Zeit FPC:  00.51.579s
Zeit libm: 00.05.044s
FPC Compiler Entwickler

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7457
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Sinus gähnend langsam unter Linux

Beitrag von af0815 »

Bei mir

ohne unit math
Plattform: Linux
Zeit FPC: 36.483s
Zeit libm: 04.982s

mit Unit math
Plattform: Linux
Zeit FPC: 20.753s
Zeit libm: 04.184s

Ich habe geglaubt, wenn ich auf die Unit math umstelle und die Funktion SinCos() verwende, wird es noch schneller, weil SinCos ja direkt in Assembler aufgelöst werden kann. Und das dann direkt über die CPU/FPU mittels fsincos berechnet wird. Irgendwie komisch, vor allen, weil es auf Linux so langsam erscheint.

Snippet aus der Unit math.

Code: Alles auswählen

procedure sincos(theta : double;out sinus,cosinus : double);assembler;
  var
    t : double;
  asm
    movsd qword ptr t,xmm0
    fld qword ptr t
    fsincos
    fstp qword ptr [cosinus]
    fstp qword ptr [sinus]
    fwait
  end;
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Mathias
Beiträge: 7368
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Sinus gähnend langsam unter Linux

Beitrag von Mathias »

Ich habe noch ein bisschen rumprobiert. Es hat einen grossen Unterschied, ob man sin oder cos rechnet.
cos läuft auf wine etwa 10x langsamer als sin, egal ob fpc oder libm. Unter linux ist die libm etwa gleich wie fpc, wen mon mit cos rechnet.
Ich werde bei Gelegenheit eine vernünftige Auswertung durch geben.

c_sinl und c_cosl kann ich unter wine nicht testen, die sind anscheinend nicht implemtiert.
Mit Lazarus sehe ich grün
Mit Java, Python und C++ sehe ich rot

Antworten