Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   ASM vs Delphi (https://www.delphipraxis.net/38224-asm-vs-delphi.html)

Kryoko 16. Jan 2005 13:41


ASM vs Delphi
 
Hi.

Wollte mal wissen was schneller ist :

Delphi-Quellcode:
function VectorSetValue(const Value:Single): TVector3D;
begin
  Result.X := Value;
  Result.Y := Value;
  Result.Z := Value
end;
oder
Delphi-Quellcode:
function VectorSetValue(const Value:Single): TVector3D;
asm
  FLD Value
  FSTP Result.X
  FLD Value
  FSTP Result.Y
  FLD Value
  FSTP Result.Z
end;
Jemand ne Idee ?

SirThornberry 16. Jan 2005 13:44

Re: ASM vs Delphi
 
führe das ganze in einer Schleife 1 000 000 mal aus und messe die zeit, dann weißt du es genau

sakura 16. Jan 2005 13:52

Re: ASM vs Delphi
 
Zitat:

Zitat von SirThornberry
führe das ganze in einer Schleife 1 000 000 mal aus und messe die zeit, dann weißt du es genau

Und anschließend teste noch folgende, welche imo die schnellste sein sollte:
Delphi-Quellcode:
function VectorSetValue(const Value:Single): TVector3D;
asm
  mov edx, Value
  mov [eax], edx
  mov [eax + $04], edx
  mov [eax + $08], edx
end;
Deren Ergebnis ist i.A. identisch zur Pascal-Lösung, verzichtet aber auf das wiederholte Laden des Übergabewertes.

Deine Lösung sollte spürbar langsamer sein, da Du auf die Befehle des Co-Prozessor zurückgreifst, während der Code von Delphi ohne diesen auskommt und einfach die Speicherwerte kopiert :zwinker:

...:cat:...

Kryoko 16. Jan 2005 13:54

Re: ASM vs Delphi
 
humm...je mehr es wird desto geringer später der unterschied...naja...asm ist erstmal schneller -
:P

_Sebastian_ 16. Jan 2005 13:55

Re: ASM vs Delphi
 
Zitat:

Zitat von SirThornberry
führe das ganze in einer Schleife 1 000 000 mal aus und messe die zeit, dann weißt du es genau

optimiert da nicht der kompiler dazwischen wenn man das einfach so inner schleife ablaufen lässt?

sakura 16. Jan 2005 14:00

Re: ASM vs Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von Kryoko
humm...je mehr es wird desto geringer später der unterschied...naja...asm ist erstmal schneller -
:P

Kann ich nicht bestätigen, aber ich weiß auch nicht wie Du gemessen hast. Anbei mal eine Sample-App mit den drei Methoden. Delphis (1) und meine (3) sind nahezu identisch, Deine (2) ca. 60% langsamer.

...:cat:...

sakura 16. Jan 2005 14:01

Re: ASM vs Delphi
 
Zitat:

Zitat von _Sebastian_
optimiert da nicht der kompiler dazwischen wenn man das einfach so inner schleife ablaufen lässt?

Nicht bei Funktionsaufrufen, aber schau mal in meine Lösung, die garantiert dass da nix mit Optimierung läuft ;-)

...:cat:...

Oxmyx 16. Jan 2005 14:05

Re: ASM vs Delphi
 
Zitat:

Zitat von Kryoko
humm...je mehr es wird desto geringer später der unterschied...naja...asm ist erstmal schneller -
:P

Delphi erzeugt auch nur Assemblercode, und bei einer einfachen Zuweisung würde ich dem Delphi-Compiler vertrauen, dass der effizienteste Code erzeugt wird.

sakura 16. Jan 2005 14:07

Re: ASM vs Delphi
 
Zitat:

Zitat von Oxmyx
und bei einer einfachen Zuweisung würde ich dem Delphi-Compiler vertrauen, dass der effizienteste Code erzeugt wird.

Er hat aber eine dreifache Zuweisung der gleichen Variablen und hier hat Delphi einen Nachteil, es lädt die Variable auch drei Mal :roll: Ansonsten ist Delphi in diesem Fall aber wirklich viel schneller, da einfach nur Speicher kopiert wird und nicht auf Co-Prozessor Befehle gesetzt wird.

...:cat:...

dizzy 16. Jan 2005 14:54

Re: ASM vs Delphi
 
Gibt es zu FSTP nicht auch die Variante ohne "Pop"? Dann ließe sich das ewige nachladen verhindern.

sakura 16. Jan 2005 15:13

Re: ASM vs Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von dizzy
Gibt es zu FSTP nicht auch die Variante ohne "Pop"? Dann ließe sich das ewige nachladen verhindern.

Ja, hat aber auch keinen echten Speed-Zuwachs. Siehe Anhang.

...:cat:...

dizzy 16. Jan 2005 15:16

Re: ASM vs Delphi
 
:shock: Das ist dann ja sogar die langsamste Variante! Sowatt!

\\edit: *hmpf* du hast nen Monitor links vom zentralen stehen, gell!? Form1.Left = -1200 oder so... Proll ;)

sakura 16. Jan 2005 15:20

Re: ASM vs Delphi
 
Zitat:

Zitat von dizzy
\\edit: *hmpf* du hast nen Monitor links vom zentralen stehen, gell!? Form1.Left = -1200 oder so... Proll ;)

Wer weiß, es war auf dem mittleren der Monitore :mrgreen:

...:cat:...

Kryoko 16. Jan 2005 18:51

Re: ASM vs Delphi
 
Hm...erstmal Danke Sakura :)
Dann werd ich mich mal dran machen und da ein bisschen nach "deinem Vorbild" verbessern...

EDIT:
Mit welchem Processor, bitte?
Bei meinem Pentium M mit 1.6 Gig ist meine Methode jedes 2.te Mal die 2. schnellste...Deine hält jedoch fast immer die spitze (1 / 10 nicht...)

:shock:

und btw: ich hab mit GetTickCount die Zeit gemessen... :|

gekmihesg 16. Jan 2005 19:08

Re: ASM vs Delphi
 
also bei mir sagt das testprogramm nur nen unterschied von so 5-10 ms
und welche methode jetzt schneller ist schwankt eigendlich dauernd.
aber vielleicht liegts daran das meine kiste so alt is...

Kryoko 16. Jan 2005 21:10

Re: ASM vs Delphi
 
Ausserdem ist es meiner bescheidene Meinung nach sehr unwahrscheinlich, das der vom Delphi-Compiler erstellte Code schneller sein soll als die von mir geschriebene Floatpointberechnung, obwohl Float register langsam sind...
Delphi added stehts Checks...
Das deins, Sakura, das schnellste ist, stimmt ;)

MaBuSE 17. Jan 2005 10:47

Re: ASM vs Delphi
 
Zitat:

Zitat von sakura
Und anschließend teste noch folgende, welche imo die schnellste sein sollte:
Delphi-Quellcode:
function VectorSetValue(const Value:Single): TVector3D;
asm
  mov edx, Value
  mov [eax], edx
  mov [eax + $04], edx
  mov [eax + $08], edx
end;
Deren Ergebnis ist i.A. identisch zur Pascal-Lösung, verzichtet aber auf das wiederholte Laden des Übergabewertes.

Bei dieser Lösung sollte man aber bedenken, dass sich durch eine Änderung am record TVector3D evtl. die Adressen ändern.

Beisp:
Delphi-Quellcode:
type
  TVector3D = record x, y, z: Single; end;
Dann funktioniert sakuras Lösung.

Delphi-Quellcode:
type
  TVector3D = record x, nein_tu_das_nicht, y, z: Single; end;
Ups, nun haben sich die Adressen geändert.
Delphi-Quellcode:
function VectorSetValue(const Value:Single): TVector3D;
asm
  mov edx, Value
  mov [eax], edx
  mov [eax + $08], edx
  mov [eax + $0c], edx
end;
Das ganze ist nun um 4 Byte verschoben, da single 4 Byte belegt.
Werden andere Typen verwendet z.B. Double statt Single, dann sind die Adressen auch entsprechend anders.

Das Delphi aus dem Original Quelltext macht, lässt sich sehr leicht mit dem CPU Fenster ermitteln.
Delphi-Quellcode:
type
  TVector3D = record x, y, z: Single; end;

function VectorSetValue(const Value:Single): TVector3D;
begin                 // <- hier Haltepunkt setzen (F5 Taste)
  Result.X := Value;
  Result.Y := Value;
  Result.Z := Value
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  x: TVector3D;
begin
  x := VectorSetValue(1);
  Caption := IntToStr(Round(x.x+x.y+x.z)); // Anmerkung: Diese Zeile ist nur da,
                                            // damit Delphi mir mein x nicht wegoptimiert ;-)
end;
Wird die Applikation mit F9 gestartet, und der Button1 gedrückt, so bleibt der Debugger an der Stelle begin (in der Funktion VectorSetValue) stehen.
Mit "Menü -> Ansicht -> Debug-Fenster -> CPU" kann man das CPU Fenster öffnen.
hier steht nun folgendes:
Code:
Unit1.pas.30: begin
  0044D944 55                 push ebp
  0044D945 8BEC              mov ebp,esp
Unit1.pas.31: Result.X := Value;
  0044D947 8B5508             mov edx,[ebp+$08]
  0044D94A 8910               mov [eax], edx
Unit1.pas.32: Result.Y := Value;
  0044D94C 8B5508             mov edx,[ebp+$08]
  0044D94F 895004             mov [eax + $04], edx
Unit1.pas.33: Result.Z := Value;
  0044D952 8B5508             mov edx,[ebp+$08]
  0044D955 895008             mov [eax + $08], edx
...
[ebp+$08] ist die Adresse von Value, also kann man auch mov edx, Value schreiben.
Da das Register edx durch ein mov [eax],edx nicht verändert wird braucht man es nicht noch mal mit der Adresse von Value zu laden.
Daraus ergibt sich Sakuras Quelltext:
Code:
  mov edx, Value
  mov [eax], edx
  mov [eax + $04], edx
  mov [eax + $08], edx
Wenn nun ein verändertes Array (z.B. Double als Typ) verwendet wird, kann man im CPU Fenster sehen, was Delphi daraus macht und sein ASM entsprechend anpassen.

pajofego 17. Jan 2005 11:12

Re: ASM vs Delphi
 
Da wir schon beim Thema sind,

habe ich ganz kurz ein Frage: Gibt es eine mit SSE/SSE2, MMX und 3dNow optimierte Bibliothek für Vektoren- und Matrizenoperationen? Am liebsten wäre mir eine in Delphi aber falls es nur in C/C++ was gibt tut es zur Not auch!

Danke,

Gruss pajofego

negaH 17. Jan 2005 11:54

Re: ASM vs Delphi
 
Delphi-Quellcode:
function VectorSetValue(const Value: Single): TVector3D;
asm
  mov edx, Value
  mov [eax].TVector3D.X, edx
  mov [eax].TVector3D.Y, edx
  mov [eax].TVector3D.Z, edx
end;
Damit erledigt sich das Problem mit dem nachträglichen Anpassen des ASM.

Gruß Hagen

Robert Marquardt 17. Jan 2005 15:24

Re: ASM vs Delphi
 
Dafuer gibt es OpenCV von Intel, aber es gibt wohl noch keine Konversion nach Delphi fuer das API.

MaBuSE 17. Jan 2005 15:47

Re: ASM vs Delphi
 
Zitat:

Zitat von pajofego
Da wir schon beim Thema sind,

Erzeuge ein neues Thema mit sprechendem Titel, dann wirst Du auch Antwort bekommen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz