![]() |
AW: [ASM / SSE] Vektoroperationen
Zitat:
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.) |
AW: [ASM / SSE] Vektoroperationen
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:
Und zur bestimmung der Länge (benutzt nicht alle 4 werte am Ende, und benutzt nicht RSQRT):
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}
Delphi-Quellcode:
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.
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} [EDIT] Performancegewinn liegt ebenfalls bei über 30% (Länge bestimmen), 50%+ (Normalisieren), gemessen auf einem i5-760 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:01 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