SSE Beschleunigung

Für allgemeine Fragen zur Programmierung mit PureBasic.
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: SSE Beschleunigung Structure Align

Beitrag von SMaag »

Kennt sich jemand mit den Aligns aus?

Die Move Befehler gibt es als Aligned und Unaligned Version

unaligned vs aligned
Movups vs. Movaps
Vmovups vs Vmovaps

Ich geh jetzt mal davon aus, dass die Aligned Befehle schneller arbeiten als die unagligend!???

ich hab hier mal die Algin-Werte an die Structures angehängt, wie ich mir das vorstelle.

1. Kann/muss man das so machen, oder macht PB das vielleicht bereits von selbst?

2. Wenn ich richtige liege, dann wäre bei den TVector3 Typen mit Align immer ein paar leere Bytes dahinter,
so dass man einen TVector3 auch wie einen TVector4 einlesen könnte und mit einem Befehl bearbeiten.
Ohne dem korrekten Align müsste man das auf 2 Befehle aufteilen. x,y zusammen und dann noch z einzeln



Structure TVector3f Align 16
x.f
y.f
z.f
EndStructure

Structure TVector4f Extends TVector3f
w.f
EndStructure

Structure TVector3d Align 32
x.d
y.d
z.d
EndStructure

Structure TVector4d Extends TVector3d
w.d
EndStructure
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: SSE Beschleunigung

Beitrag von SMaag »

hat sich erledigt, ich hab's begriffen.

Das mit den Align 16 bzw 32 geht nicht, da PB nicht die Structur an sich ausrichtet, sondern jede Variable in der Structur ist dann 16(32Byte
ausgerichtet. Und das ist nicht der Sinn.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: SSE Beschleunigung

Beitrag von mk-soft »

Schau dir mal StructureUnion an. Damit kann man einzelne Variablen oder strukturen überlagern. (Ausser Strings)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: SSE Beschleunigung

Beitrag von SMaag »

der Tipp mit UnionStructure hat mich auf eine Idee gebracht.

; Vector ist immer aus 4 Elementen, sonst macht das keinen Sinn
; die Unterscheidung Vector3, Vector4 bringt nur Nachteile statt Vorteile.
; Man muss nur zwischen SingleVectoren und DoubleVectoren unterscheiden.
; Dann braucht man neben den x,y,z,w Kooridnaten noch die Möglichkeit des
; indizierten Zugriffs. Dies dürfte für Matrix-Operationen besser sein!

mit der Union Länge 0 hat man noch eine Indizierung
So hab ich jetzt die optimierte Vector Struct zusammengebaut.

Code: Alles auswählen

 Structure TsVector  ; Single precicion Vector [16 Bytes / 128 Bit]
    StructureUnion
      v.f[0]          ; virutal Array  v[0]=x, v[1]=y, v[2]=z, v[3]=w
    EndStructureUnion
    x.f
    y.f
    z.f
    w.f
  EndStructure 
 
  Structure TdVector  ; Double precicion Vector [32 Bytes / 256 Bit]
    StructureUnion
      v.d[0]          ; virutal Array  v[0]=x, v[1]=y, v[2]=z, v[3]=w
    EndStructureUnion
    x.d
    y.d
    z.d  
    w.d
  EndStructure

Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: AVX Beschleunigung für Double Vectoren

Beitrag von STARGÅTE »

SMaag hat geschrieben: 06.12.2022 17:35 Debug Ausdruck; das müsste bei 32-Bit-Single und 64-Bit-Double das gleiche Ergebnis sein!
Es wird aber nur X und Z bearbeitet und ist auch noch falsch!
In deinem Code mit den YMM Registern sind noch Fehler drin.
So verwendest bei du Doubles immer noch packed single (...ps) statt packed double (...pd) in den ASM Befehlen.
SMaag hat geschrieben: 06.12.2022 17:50 Kennt sich jemand mit den Aligns aus?
Die Move Befehler gibt es als Aligned und Unaligned Version

Ich geh jetzt mal davon aus, dass die Aligned Befehle schneller arbeiten als die unagligend!???
Das Align hinter dem Strukturnamen bezieht dich auf die Ausrichtung der Felder in der Struktur selbst.
Das heißt bei einem Align 8 würde ein Feld mit Word.w trotzdem 8 Byte beanspruchen, damit das Feld danach wieder Ausgerichtet ist.
Das heißt aber nicht das die Variable selbst (mit dieser Struktur) auch ausgerichtet ist.
Die Speicherzuweisung ist bei 32/64 bit Prozessoren üblicherweise immer 4 bzw. 8 Byte, also nicht 16 bzw. 32 Byte wie es für Movaps oder Movapd nötig wäre.
Somit ist das in PureBasic (soweit ich weiß) nicht möglich, außer du verwaltest die Speicherzuweisung selbst.
SMaag hat geschrieben: 06.12.2022 21:17 Vector ist immer aus 4 Elementen, sonst macht das keinen Sinn
die Unterscheidung Vector3, Vector4 bringt nur Nachteile statt Vorteile.
Man muss nur zwischen SingleVectoren und DoubleVectoren unterscheiden.
Dann braucht man neben den x,y,z,w Kooridnaten noch die Möglichkeit des
indizierten Zugriffs. Dies dürfte für Matrix-Operationen besser sein!
Der erste Teil ist richtig. Selbst wenn ein Programm eigentlich nicht mit der w-Koordinate arbeitet, ist die 4er-Operation immer schneller als umständlich mit der 3er zu rechnen, weil man ja nicht einfach die XMM Befehle verwenden darf, wenn für den Speicher eigentlich nur 3*4 Byte reserviert wurden (IMA).
Der Zweite Teil ist eigentlich unwichtig. Wenn du schon alles auf SSE optimierst, dann werden natürlich auch die ganzen Matrixoperationen mit SSE implementiert. Und selbst wenn nicht, würde man eh nicht mit einer For-Schleife durch die 4 Koordinaten laufen, weil dann der Overhead der Schleife alles an Optimierung zu Nichte macht.
Du siehst ja in meinem Include, dass die Matrix auch aus 16 Feldnahmen besteht.

Was du noch überlegen solltest ist, ob du wirklich stur beim 4er-Vector die vier Koordinaten addieren/subtrahieren oder sonst was machen willst oder ob du den w-Parameter "sauber" verrechnest.
Damit meine ich, dass w=0 ja für eine Richtung steht und w=1 für einen Ort, was für die Matrixoperationen wichtig wird, ob ein Punkt z.B. durch die Matrix auch verschoben werden soll oder eine Richtung eben nicht.
Entsprechend sollte man bei Operationen wie Addition dann aufpassen, das w+w nicht zu 2 wird oder gar negativ.
Das aber nur am Rande.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: SSE Beschleunigung

Beitrag von SMaag »

Damit meine ich, dass w=0 ja für eine Richtung steht und w=1 für einen Ort, was für die Matrixoperationen wichtig wird, ob ein Punkt z.B. durch die Matrix auch verschoben werden soll oder eine Richtung eben nicht.
Wofür steht das w? Das muss mir mal jemand im Detail erklären!
Ich hab was gelesen, dass w=[0/1] 0der 1/z ist ???

Ich hab das jetzt ziemlich weit angepasst und geteset!
Wat für N' Scheiß, den Assembler-Code für die Double Version in AVX hin zu bekommen!

Es funktioniert bei mir in x32 compliert
bis zum Vector_Swap,
VectorCross-Product hat dann Fehler!

Leider schaff ich es nicht hier einen Dateianhang hoch zu laden.
Deswegen ist die aktuelle Version auf Github

https://github.com/Maagic7/PureBasicFra ... ule_MMX.pb

Hoffe mal auf etwas Unterstützung für das Testen. Bzw. Verbesserungen.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: SSE Beschleunigung

Beitrag von STARGÅTE »

SMaag hat geschrieben: 07.12.2022 22:10 Wofür steht das w? Das muss mir mal jemand im Detail erklären!
Ich hab was gelesen, dass w=[0/1] 0der 1/z ist ???
Das hatte ich doch in meinem vorherigen Post geschrieben. Richtungsvektoren (z.B. Normalen, Längen oder Abstände) bekommen ein w=0 sodass die Ortsverschiebung der 4x4-Matrix nicht auf sie wirkt (weil dann 0 * letze Spalte gerechnet wird). Punkte und Orte haben ein w=1, dadurch wird die Ortsverschiebung der Matrix berücksichtigt.
Beim Rendern wird das w auch oft als 1/z genutzt, vor allem dann wenn es um Projektionen geht.
SMaag hat geschrieben: 07.12.2022 22:10 Es funktioniert bei mir in x32 compliert
bis zum Vector_Swap,
VectorCross-Product hat dann Fehler!
Hast du denn keine Möglichkeit x64 zu testen?
Dein Kreuzprodukt ist fehlerhaft, weil du yzw kreuzt statt xyz. Dein SHUFPS ist falsch.
Bei meinem Drawing3D code ist die Reihenfolge w,x,y,z weil ich dann besser an das w mit den scalaren SSE Befehlen rankomme und das w ja eine Sonderfunktion hat.
Du hast (wie es auch üblich ist) aber x,y,z,w. Hier musst du also 11001001b bzw. 11010010b shuffeln.
SMaag hat geschrieben: 07.12.2022 22:10 Hoffe mal auf etwas Unterstützung für das Testen. Bzw. Verbesserungen.
Da kann ich mich glaube ich nicht zu motivieren, weil ich das was du gerade machst, bereits fertig habe :twisted:. Ich hatte das damals für meine 3D-Engine gemacht, hatte somit auch Feldtests.

Kleiner Tip von mir: Da du ja eh gerne mit Macros arbeitest, wären genau hier wo du viel redundaten ASM code hast (z.B. für Shuffel oder bei der Matrixmultiplikation) kleine Macros sinnvoll um den Code zu verkleinern.
Als Beispiel: Hier werden ja die Macroargumente auch im ASM ersetzt. Muss man natürlich ater klarer benennen.

Code: Alles auswählen

Macro PshufdMulpsAddps(reg, shufle)
	!Pshufd Xmm1, Xmm2, shufle
	!Mulps  Xmm1, reg
	!Addps  Xmm0, Xmm1
EndMacro

PshufdMulpsAddps(Xmm5, 01010101b)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: SSE Beschleunigung

Beitrag von SMaag »

@STARGATE

Danke nochmals! Jetzt hab ich's kapiert.

Mit den Grafiksachen hatte ich bisher nichts am Hut. Vector und Matrix
vom Studium, aber eben für Anwendung in der Elektrotechnik und
ein paar Jahre her.
Wenn das alles wieder da ist, dann versteh ich das auch.
Dauert nur immer etwas.
Ich programmiere normalerweise hauptsächlich Industriesteuerungen.
Daher ist Assembler grundsätzlich auch kein Problem. Nur mit dem x86 ASM
hatte ich bisher relativ wenig zu tun.

Da helfen schon diese kleinen Tipps hier meist recht gut weiter!
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: 3DDrawingModul

Beitrag von SMaag »

@STARGATE

uuuiii, nachdem ich das mit deinem Tipp kapiert hatte, hab ich nochmals deine 3DDrawingDemo probiert!
Jetzt hat das auf einmal coole Farben!!! Das war vorher nicht der Fall!

Was war passiert!
PureBasic 6.0 meckert beim Code, dass Vector4 bereits definiert ist. Das hat Purebasic anscheinend seit V6.0 integriert.
Dort aber mit X,Y,Z,W und bei 3dDrawing mit W,X,Y,Z

Ich hatte die Defintion von Vector4 einfach auskommentiert. Das ging, halt ohne Farben! Fällt aber so weiter nicht auf!

Nachdem ich das nun auf Vector4f umbenannt habe sieht das noch besser aus!
Antworten