AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Verbesserungsvorschläge für Vector3 Class
Thema durchsuchen
Ansicht
Themen-Optionen

Verbesserungsvorschläge für Vector3 Class

Ein Thema von Lyan · begonnen am 18. Mai 2019 · letzter Beitrag vom 21. Mai 2019
Antwort Antwort
Lyan

Registriert seit: 5. Aug 2011
188 Beiträge
 
#1

Verbesserungsvorschläge für Vector3 Class

  Alt 18. Mai 2019, 01:10
Delphi-Version: 10.2 Tokyo
Ich hatte/habe Probleme eine simple, effiziente Vector3-Klasse zu finden, die außerdem auch zugriff via [] erlaubt. Habe also heute meine eigene geschrieben, habe ein paar Fragen dazu.

1) Ist es möglich Heap/Stack in Delphi immer 16 Byte zu alignen, dass ich movaps anstatt movups nutzen kann? Heap whs. via custom allocator, Stack finde ich gar keine Lösung zu.
2) Um movups überhaupt zu verwenden, musste ich 128 bit (Values: array[0..3] of Single) allocaten. Alternativ hätte ich movq/movss nutzen können, jetzt stellt sich mir allgemein die Frage was schneller ist und ob man das als extrem unschön ansehen sollte dass ich 4 anstatt 3 Singles habe. Ich sehe halt das Problem, wenn man davon ausgeht dass es 3 Werte sind und SizeOf(TVector3) macht man überrascht sein könnte.
3) Kann man das mit dem property access "[]" so wie ich es gemacht habe verbesser? Ich habe extra keinen Index check, ich rede eher von anderen Methoden, wie ich es z.B. aus c++ gewöhnt war mit operator [] überschreiben.
4) In c++ hätte ich die Vectors als const referenz übergeben. Also hier ja dann eigtl. const var? Wie geht das?
5) Allgemeine verbesserungen

Weiteres: Ich habe hier entnommen, dass ab Ryzen oder Skylake keine Performance-Unterschiede mehr sind zwischen movups/movaps (und bei neuren Prozessoren whs.).

Danke für die Hilfe!

Delphi-Quellcode:
unit UnitVector3;

interface

type TVector3 = record
  private
    FValues: array[0..3]of Single;
    function GetValue(AIndex: Integer): Single; inline;
    procedure SetValue(AIndex: Integer; AValue: Single); inline;
  public
    // properties
    property X: Single read FValues[0] write FValues[0];
    property Y: Single read FValues[1] write FValues[1];
    property Z: Single read FValues[2] write FValues[2];
    property Values[AIndex: Integer]: Single read GetValue write SetValue; default;

    // funcs
    class function Create(const AX, AY, AZ: Single): TVector3; inline; static;
    procedure SetNormalize;
    function Normalize: TVector3;
    function Length: Single;
    function LengthSquared: Single;
    function Length2D: Single;
    function LengthSquared2D: Single;
    function Dot(const B: TVector3): Single;
    function Cross(const B: TVector3): TVector3;
    function Distance(const B: TVector3): Single;
    function DistanceSquared(const B: TVector3): Single;

    // operators
    class operator Negative(const A: TVector3): TVector3; inline;
    class operator Positive(const A: TVector3): TVector3; inline;
    class operator Equal(const A, B: TVector3): Boolean; inline;
    class operator NotEqual(const A, B: TVector3): Boolean; inline;

    // Vector mit Vector
    class operator Add(const A, B: TVector3): TVector3;
    class operator Subtract(const A, B: TVector3): TVector3;
    class operator Multiply(const A, B: TVector3): TVector3;
    class operator Divide(const A, B: TVector3): TVector3;

    // Vector mit Single
    class operator Add(const A: TVector3; const B: Single): TVector3;
    class operator Subtract(const A: TVector3; const B: Single): TVector3;
    class operator Multiply(const A: TVector3; const B: Single): TVector3;
    class operator Divide(const A: TVector3; const B: Single): TVector3;

    // Single mit Vector
    class operator Add(const A: Single; const B: TVector3): TVector3;
    class operator Subtract(const A: Single; const B: TVector3): TVector3;
    class operator Multiply(const A: Single; const B: TVector3): TVector3;
    class operator Divide(const A: Single; const B: TVector3): TVector3;
end;

implementation

{ TVector3 }

class operator TVector3.Add(const A, B: TVector3): TVector3; assembler;
asm
  movups xmm0, [A]
  movups xmm1, [B]
  addps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Add(const A: TVector3; const B: Single): TVector3; assembler;
asm
  movups xmm0, [A]
  movss xmm1, [B]
  shufps xmm1, xmm1, 0
  addps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Add(const A: Single; const B: TVector3): TVector3; assembler;
asm
  movups xmm0, [B]
  movss xmm1, [A]
  shufps xmm1, xmm1, 0
  addps xmm0, xmm1
  movups [Result], xmm0
end;

class function TVector3.Create(const AX, AY, AZ: Single): TVector3;
begin
  Result.X := AX;
  Result.Y := AY;
  Result.Z := AZ;
end;

function TVector3.Cross(const B: TVector3): TVector3; assembler;
asm
  movups xmm0, [Self]
  movups xmm1, [B]
  movaps xmm2, xmm0
  movaps xmm3, xmm1
  shufps xmm0, xmm0, $C9
  shufps xmm1, xmm1, $D2
  mulps xmm0, xmm1
  shufps xmm2, xmm2, $D2
  shufps xmm3, xmm3, $C9
  mulps xmm2, xmm3
  subps xmm0, xmm2
  movups [Result], xmm0
end;

function TVector3.Distance(const B: TVector3): Single; assembler;
asm
  movups xmm0, [Self]
  movups xmm1, [B]
  subps xmm0, xmm1
  dpps xmm0, xmm0, $71
  sqrtps xmm0, xmm0
  movss [Result], xmm0
end;

function TVector3.DistanceSquared(const B: TVector3): Single; assembler;
asm
  movups xmm0, [Self]
  movups xmm1, [B]
  subps xmm0, xmm1
  dpps xmm0, xmm0, $71
  movss [Result], xmm0
end;

class operator TVector3.Divide(const A: Single; const B: TVector3): TVector3; assembler;
asm
  movups xmm0, [B]
  movss xmm1, [A]
  shufps xmm1, xmm1, 0
  divps xmm0, xmm1
  movups [Result], xmm0
end;

function TVector3.Dot(const B: TVector3): Single; assembler;
asm
  movups xmm0, [Self]
  movups xmm1, [B]
  dpps xmm0, xmm1, $71
  movss [Result], xmm0
end;

class operator TVector3.Divide(const A: TVector3; const B: Single): TVector3; assembler;
asm
  movups xmm0, [A]
  movss xmm1, [B]
  shufps xmm1, xmm1, 0
  divps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Divide(const A, B: TVector3): TVector3; assembler;
asm
  movups xmm0, [A]
  movups xmm1, [B]
  divps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Equal(const A, B: TVector3): Boolean;
begin
  Result := (A.X = B.X) and (A.Y = B.Y) and (A.Z = B.Z);
end;

function TVector3.GetValue(AIndex: Integer): Single;
begin
  Result := FValues[AIndex];
end;

function TVector3.Length: Single; assembler;
asm
  movups xmm0, [Self]
  dpps xmm0, xmm0, $71
  sqrtps xmm0, xmm0
  movss [Result], xmm0
end;

function TVector3.Length2D: Single; assembler;
asm
  movups xmm0, [Self]
  dpps xmm0, xmm0, $31
  sqrtps xmm0, xmm0
  movss [Result], xmm0
end;

function TVector3.LengthSquared: Single; assembler;
asm
  movups xmm0, [Self]
  dpps xmm0, xmm0, $71
  movss [Result], xmm0
end;

function TVector3.LengthSquared2D: Single; assembler;
asm
  movups xmm0, [Self]
  dpps xmm0, xmm0, $31
  movss [Result], xmm0
end;

class operator TVector3.Multiply(const A: Single; const B: TVector3): TVector3; assembler;
asm
  movups xmm0, [B]
  movss xmm1, [A]
  shufps xmm1, xmm1, 0
  mulps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Multiply(const A: TVector3; const B: Single): TVector3; assembler;
asm
  movups xmm0, [A]
  movss xmm1, [B]
  shufps xmm1, xmm1, 0
  mulps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Multiply(const A, B: TVector3): TVector3; assembler;
asm
  movups xmm0, [A]
  movups xmm1, [B]
  mulps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Negative(const A: TVector3): TVector3;
begin
  Result.X := -A.X;
  Result.Y := -A.Y;
  Result.Z := -A.Z;
end;

function TVector3.Normalize: TVector3; assembler;
asm
  movups xmm0, [Self]
  movaps xmm1, xmm0
  dpps xmm0, xmm0, $7F
  rsqrtps xmm0, xmm0
  mulps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.NotEqual(const A, B: TVector3): Boolean;
begin
  Result := (A.X <> B.X) or (A.Y <> B.Y) or (A.Z <> B.Z);
end;

class operator TVector3.Positive(const A: TVector3): TVector3;
begin
  Result := A;
end;

procedure TVector3.SetNormalize; assembler;
asm
  movups xmm0, [Self]
  movaps xmm1, xmm0
  dpps xmm0, xmm0, $7F
  rsqrtps xmm0, xmm0
  mulps xmm0, xmm1
  movups [Self], xmm0
end;

procedure TVector3.SetValue(AIndex: Integer; AValue: Single);
begin
  FValues[AIndex] := AValue;
end;

class operator TVector3.Subtract(const A: Single; const B: TVector3): TVector3; assembler;
asm
  movups xmm0, [B]
  movss xmm1, [A]
  shufps xmm1, xmm1, 0
  subps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Subtract(const A: TVector3; const B: Single): TVector3; assembler;
asm
  movups xmm0, [A]
  movss xmm1, [B]
  shufps xmm1, xmm1, 0
  subps xmm0, xmm1
  movups [Result], xmm0
end;

class operator TVector3.Subtract(const A, B: TVector3): TVector3; assembler;
asm
  movups xmm0, [A]
  movups xmm1, [B]
  subps xmm0, xmm1
  movups [Result], xmm0
end;

end.

Geändert von Lyan (18. Mai 2019 um 02:06 Uhr)
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
2.824 Beiträge
 
Delphi 12 Athens
 
#2

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 18. Mai 2019, 08:42
Zur Steuerung der Allokation gibt es die $A Direktive. Schon geschaut, ob die inzwischen auch 16 Byte ALlokation kann?
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.126 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 18. Mai 2019, 10:11
Habe also heute meine eigene geschrieben...
I like this Idea to have an ASM Vector Lib.

But it had to be multiplattform/CPU and 32/64.

Perhaps you like to take a look at this!

Mavarik
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.060 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 20. Mai 2019, 08:31
Warum antwortest du auf englisch?
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 20. Mai 2019, 09:16
Babylon.

Sieht gar nicht übel aus, aber grade bei so wildem Assembler-Kram - Gibt es keine Tests?
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.380 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 20. Mai 2019, 13:43
Nun ja die Grundsatzfrage ist, ob das nur für ihn ist oder auch für andere. Das "und SizeOf(TVector3) macht man überrascht sein könnte." deutet vielleicht eher auf letzteres. Dann fehlt auch noch Doku, unter anderem zuerst was ein Vector3 denn ist. (In unser Software haben wir tausende an Vektor-Rechnungen, der Begriff ist mir noch nicht untergekommen, google hilft auch wenig weiter.)
Was für uns die unit unbrauchbar macht ist, dass die auf Single basiert und nicht auf Double.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.060 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 20. Mai 2019, 15:01
Dann fehlt auch noch Doku, unter anderem zuerst was ein Vector3 denn ist. (In unser Software haben wir tausende an Vektor-Rechnungen, der Begriff ist mir noch nicht untergekommen, google hilft auch wenig weiter.)
Hm, wenn ich "Vector3" in Google eingebe kommt unter den ersten vier Suchtreffern:
https://docs.unity3d.com/ScriptReference/Vector3.html
https://docs.microsoft.com/de-de/dot...tframework-4.8

Ist wohl nicht ganz so unüblich als Benennung.

Also ein Vektor im Raum der durch die Koordinaten x, y, z definiert ist.

Wie heißen denn eure Vektoren-Datentypen?
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 20. Mai 2019, 16:37
Ich finde Vector3 eigentlich auch eindeutig als Namen.
Nur mir fehlt wirklich Doku, der Quelltext hilft mir leider nicht weiter. Stell es doch auf z.B. Github, der ein oder andere (z.B ich) macht sicher gerne ein paar Tests dafür...
  Mit Zitat antworten Zitat
Benutzerbild von TRomano
TRomano

Registriert seit: 24. Nov 2004
Ort: Düsseldorf
190 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 21. Mai 2019, 08:35
Hallo,

unter https://www.agner.org/optimize/ findest Du die aktuellsten Ressourcen zur Optimierung von Assembler-Source auf die verschiedenen CPU´s.

Nun ja, es gibt schon noch Unterschiede von (v)movups und (v)movaps. In den dort hintelegten Instruction tables von Prof. Agner kannst du das wunderbar für jeden Prozessor nachlesen. Das geht bis zu den Ryzens von AMD.
Wahrscheinlich ist das derartig verallgemeinert worden, weil es kaum mehr große Unterschiede macht, ob die Mov-Befehle mit oder oder entsprechendes Alignment benutzt. Zu mindestens bei diesen relativ kleinen Jobs in deinen Routinen. Bei der Bearbeitung riesiger Datenmengen kann das allerdings immer noch einen Unterschied machen.
Leider unterstützt Delphi noch immer kein AVX, AVX2, geschweige den AVX5212 mit all seinen Derivaten, direkt, so das man hier zu externen Assemblern greifen muss und dann die entsprechenden Object-Files einbinden muss.

Gruß Thomas
Thomas Forget
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.126 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: Verbesserungsvorschläge für Vector3 Class

  Alt 21. Mai 2019, 10:18
Warum antwortest du auf englisch?

Keinen Plan... Sorry...

War sicherlich gerade mit anderen im Chat...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:32 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz