AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

[ASM / SSE] Vektoroperationen

Ein Thema von Edlmann · begonnen am 13. Jun 2012 · letzter Beitrag vom 18. Jun 2012
Antwort Antwort
Edlmann

Registriert seit: 19. Nov 2010
212 Beiträge
 
#1

AW: [ASM / SSE] Vektoroperationen

  Alt 14. Jun 2012, 14:45
Vielen Dank für die Erklärung.

Habs mit 16 byte Alignment am Laufen, doch der Gewinn an Geschwindigkeit beträgt +-0... werd mir also den Aufwand damit sparen, und es bei ganz normalen Arrays lassen.

Allerdings hab ich noch immer keine alternative zu addpsh ( Vertikales aufaddieren eines MMX Registers ) gefunden, falls man nur mit SSE1 arbeiten möchte...Hat da jemand einen Plan, wie man das effizient realisieren kann? Der von mir oben vorgestellte Lösungsansatz ist nicht wirklich schneller als das ganze ohne SSE zu machen.

Geändert von Edlmann (14. Jun 2012 um 15:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.399 Beiträge
 
Delphi 12 Athens
 
#2

AW: [ASM / SSE] Vektoroperationen

  Alt 14. Jun 2012, 14:50
Was mir aber noch einfällt.

Gut, die GPU mag schneller sein, als das SSE,
aber wenn nicht viel/lange gerechnet wird, lohnt es sich dann übberhaupt die GPU zu nutzen?

Schlißelich muß ja erstmal alles zu der rüber und danach dann wieder zurück.
Nicht alle GPUs unterstüzen sowas und ich glaub nicht, daß alle aktuellen GPUs eine einheitliche Schnittstelle anbieten. (is doch bestimmt schlimmer als SSE auf den verschiedenen CPUs)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Medium

Registriert seit: 23. Jan 2008
3.688 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: [ASM / SSE] Vektoroperationen

  Alt 15. Jun 2012, 02:44
Gut, die GPU mag schneller sein, als das SSE, aber wenn nicht viel/lange gerechnet wird, lohnt es sich dann übberhaupt die GPU zu nutzen?
Nein, aber das gilt in ähnlicher Weise ja wie schon erwähnt wurde auch für SSE. Bei der GPU natürlich noch "schlimmer", aber sobald man ein paar hundert Operationen in einem Rutsch braucht wird's schon recht lohnenswert. Ich lechtze ja schon nach dem Tag, an dem GPU Programmierung ohne externe Libs und Schnittstellenverrenkungen direkt in den Sprachen/Compilern/Standardlibs auftauchen

Die Schnittstellen sind allerdings auch heute schon recht einheitlich, vor allem im Falle von OpenCL. Damit lassen sich imho alle aktuelleren Chips von den beiden großen Herstellern recht effizient nutzen. Da kommt JIT übrigens voll auf seine Kosten, da die Compiler in den Treibern ganze Arbeit machen beim Optimieren auf den tatsächlichen vorhandenen Chip. Auch schon bei den Shadern. Was aber immer bleibt: Sinnvoll nur, wenn man Massen an gleichstrukturierten Daten am Stück da durch schubsen kann. Es lohnt sich in einigen Fällen aber auch sehr, ein Teilprogramm daraufhin explizit auszulegen (Scatter/Gather z.B.)
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)
  Mit Zitat antworten Zitat
Edlmann

Registriert seit: 19. Nov 2010
212 Beiträge
 
#4

AW: [ASM / SSE] Vektoroperationen

  Alt 18. Jun 2012, 16:37
Falls es jemanden interessiert, hab eine Lösung gefunden, wie man mit SSE einen Vektor normalisieren kann. Den genauen Performancegewinn muss ich noch messen, werd ich dann posten, aber läuft auf jeden fall schneller als die Alternative:

Delphi-Quellcode:
function TVec4.Normalize: Single;
//Compilieren mit asm?
{$IFDEF USEASM}
asm
  MOVUPS XMM0, DQWORD PTR[&self]
  //Copy stored in MMX2
  MOVAPS XMM2, XMM0
  //Quadrupe MMX0
  MULPS XMM0, XMM0
  //Store Copy of Quadrupled Values in MMX1
  MOVAPS XMM1, XMM0
  SHUFPS XMM0, XMM1, $4e //0100 1110
  //XMM0 = z^2 w^2 x^2 y^2
  //XMM1 = x^2 y^2 z^2 w^2
  ADDPS XMM0, XMM1
  //XMM0 z^2 + x^2, w^2 + y^2, z^2 + x^2, w^2 + y^2
  MOVAPS XMM1, XMM0
  SHUFPS XMM1, XMM1, $11 //0001 0001
  //XMM1 w^2 + y^2, z^2 + x^2, w^2 + y^2, z^2 + x^2
  ADDPS XMM0, XMM1
  //XMM0 z^2 + x^2 + w^2 + y^2
  //Return the length
  SQRTSS XMM3, XMM0
  MOVSS [&Result], XMM3
  //Multiply with Rect Sqrt - Very Fast due to CPU-Internal LookUp Table
  RSQRTPS XMM0, XMM0
  MULPS XMM2, XMM0
  MOVUPS DQWORD PTR[&self], XMM2
end;
{$ELSE}
var
  i: Single;
begin
  i := Length;
  //If the length is zero, don't touch the vector
  if i = 0 then
    Exit(0);

  i := 1 / i;

  //w shouldnt be touched
  x := x * i;
  y := y * i;
  z := z * i;
  //Return the length
  Exit(i);
end;
{$ENDIF}
Und zur bestimmung der Länge (benutzt nicht alle 4 werte am Ende, und benutzt nicht RSQRT):

Delphi-Quellcode:
function TVec4.Length: Single;
//Compilieren mit asm?
{$IFDEF USEASM}
asm
  MOVUPS XMM0, DQWORD PTR [&self]
  //Quadrupe MMX0
  MULPS XMM0, XMM0
  //Store Copy of Quadrupled Values in MMX1
  MOVAPS XMM1, XMM0
  SHUFPS XMM0, XMM1, $4e //0100 1110
  //XMM0 = z^2 w^2 x^2 y^2
  //XMM1 = x^2 y^2 z^2 w^2
  ADDPS XMM0, XMM1
  //XMM0 z^2 + x^2, w^2 + y^2, z^2 + x^2, w^2 + y^2
  MOVAPS XMM1, XMM0
  SHUFPS XMM1, XMM1, $11 //0001 0001
  //XMM1 w^2 + y^2, z^2 + x^2, w^2 + y^2, z^2 + x^2
  ADDSS XMM0, XMM1
  //XMM0 z^2 + x^2 + w^2 + y^2
  //Multiply with Sqrt - Very Fast due to CPU-Internal LookUp Table
  SQRTPS XMM0, XMM0
  MOVSS Result, XMM0
end;
{$ELSE}
begin
  result := Sqrt(x * x + y * y + z * z + w * w);
end;
{$ENDIF}
Diese Algorithmen sind aufgrund der CPU-Internen Lookup-Tabelle für Sqrt ungenauer als die Berechnung über delphi's sqrt, aber trotzdem noch ziemlich genau, sollten also für die meisten Berechnungen reichen. Wenns jedoch um Genauigkeit geht und die Zeit egal ist, sollte man nicht die SSE-Variante benutzen.

[EDIT]

Performancegewinn liegt ebenfalls bei über 30% (Länge bestimmen), 50%+ (Normalisieren), gemessen auf einem i5-760

Geändert von Edlmann (18. Jun 2012 um 17:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#5

AW: [ASM / SSE] Vektoroperationen

  Alt 14. Jun 2012, 15:30
Allerdings hab ich noch immer keine alternative zu addpsh ( Vertikales aufaddieren eines MMX Registers ) gefunden, falls man nur mit SSE1 arbeiten möchte...Hat da jemand einen Plan, wie man das effizient realisieren kann? Der von mir oben vorgestellte Lösungsansatz ist nicht wirklich schneller als das ganze ohne SSE zu machen.
Nein. Gibt es nicht. Genau da setzte vorhin ja meine Kritik an. Elementare Funktionen sind nicht vorhanden. Es gibt auch keinen wirklich sinnvollen Umweg. Entweder man macht es per Hand mit der FPU oder man sortiert aufwendig irgendwelche einzellnen Singles umher. Ob das SSE 1.0 überhaupt kann weiß ich jedoch nicht.

http://softpixel.com/~cwright/programming/simd/sse.php

Zitat:
Gut, die GPU mag schneller sein, als das SSE,
aber wenn nicht viel/lange gerechnet wird, lohnt es sich dann übberhaupt die GPU zu nutzen?
Lohnt es sich dann, sich in SSE einzuarbeiten oder reicht die heutzutage durchaus schnelle Pipeline der normalen CPU/FPU?
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Edlmann

Registriert seit: 19. Nov 2010
212 Beiträge
 
#6

AW: [ASM / SSE] Vektoroperationen

  Alt 14. Jun 2012, 15:58
Ja, das hin und herschieben geht, mit SHUFPS, ist schon seit SSE1 dabei - Der Ansatz fürs Kreuzprodukt den ich weiter oben gepostet hatte benutzt das ganze auch.
  Mit Zitat antworten Zitat
Benutzerbild von Desmulator
Desmulator

Registriert seit: 3. Mai 2007
Ort: Bonn
169 Beiträge
 
#7

AW: [ASM / SSE] Vektoroperationen

  Alt 14. Jun 2012, 16:04
shufps bringt dir garnichts. Damit kannst du nur die Reihenfolge innerhalb ändern. Aber du musst alle in einer Zeile addieren. Eigentlich müssten alle aus der ersten Zeile in die erste Spalte geschoben werden, alle aus der zweiten Zeile in die zweite Spalte usw. Dann könntest du addieren, aber das ist afaik nicht möglich.
Lars
There are 10 kinds of people in the world:
those who get binary, and those who don’t.
  Mit Zitat antworten Zitat
Edlmann

Registriert seit: 19. Nov 2010
212 Beiträge
 
#8

AW: [ASM / SSE] Vektoroperationen

  Alt 14. Jun 2012, 16:39
Naja, es ginge, allerdings bräuchte man 4 Register. Das 1ste bleibt wies ist, beim 2. Packst du das 2. Element an 1. Stelle mit shufps, beim 3. das 3., beim 4. das 4., und 3 additionen später hätte man das Ergebnis an der 1sten Stelle des StartRegisters (wenn man all die geshuffelten Register aufs Startregister addiert). Wär aber sowas von umständlich.

[Edit]

Was mir noch fehlt ist ein wenig Dokumentation zu System.TestSSE...weiß jemand von euch was die weiteren Bits davon bedeuten? Auf meinem i5-760 mit SSE bis zu 4.2 enthält TestSSE 127, der einzige KOmmentar dazu sagt jedoch dass nur Bits 1 und 2 Bedeutung hätten...1 für SSE 1, 2 für SSE2...

[Edit 2]

Okey, TestSSE macht nichts anderes, als die CPUID bits auszulesen, wobei hier das 25. Bit für SSE und das 26. für SSE2 steht. Anscheinend gibt es keine wirkliche Möglichkeit, SSE3 Unterstützung auszulesen

Geändert von Edlmann (14. Jun 2012 um 17:15 Uhr)
  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 00:52 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