__declspec(align(16)) und Parameter
-
Hi,
ich hab ein kleines Problem. Ich möchte meine Mathe Bibi ein bischen mit SSE aufrüsten. So... das ist auch noch kein Problem, aber für die bestmögliche Nutzung von SSE sollten die Strukturen, wie z.B. für einen 4D Vektor, auf 16Byte Optimiert sein. Sonst muss man immer auf die movups Funktion umsteigen und kann auch nich schönen kurzen Code schreiben da einfach alles in ein XMM Register gepackt werden muss und das mit der entwas langsameren movups Funktion
Dummerweise mecker VC++ .NET wenn ich jetzt eine auf 16Byte ausgerichtete Struktur als Parameter übergeben möchte. Gibt es da eine möglichkeit wie ich das umgehen kann? Oder eine Einstellung mit dem der Compiler das akzeptiert? Ich will nicht auf movups umsteigen müssen.
-
Das Problem ist, dass wenn du eine Funktion alignest - du inkompatibel zu anderen Funktionen bist.
Denn du kannst ja nicht einmal eine struct als auf 16Bit alignen und einmal auf 32 oder so.
entweder du alignst _alles_ auf diese 16bit, oder du schreibst 'wrapper', die die struct in eine 16bit aligned struct umkopieren oder du verzichtest ganz darauf.
eine andere Möglichkeit sehe ich momentan nicht.
-
Geht doch:
__declspec(align(16)) struct Vector4D { float f1; float f2; float f3; float f4; }; void test(const Vector4D& v) { } int main() { Vector4D v; test(v); }
-
@Shade Of Mine
Du meinst wohl auf 16Byte nicht 16BitEs ist doch eigentlich nur die Ausrichtung? Und dem Stack ist es doch egal ob ich für einen Parameter nun 4Byte pushe oder 16.
Das weis man ja, es ist ja in der Struktur Definiert. Aber nagut.
Eine Wrapperklasse würde den gesamten Performancegewinn wieder aufressen. Es sind Basisfunktionen die mehrere 100mal pro Frame aufgerufen werden, da kann ich nicht dauernt eine umschichtung durchführen. Das währen bei 100 Aufrufen 200 Umschichtungen.@vector4d:
Mit Pointern geht es auch. Das ist nicht das Problem, aber in diesem Beispiel geht es schon nicht mehr:struct DataBla { int iFlag; Vector4D vPos; }; void foo(DataBla bla) { // mache was mit DataBla }
Alleine schon die Struktur DataBla kann man nicht so Definieren und man kann ja auch nicht für jeden Vektor Speicher reservieren, dann ist der gesamte Performance Vorteil schon wieder weg.
Ich weis nicht. Dann machen die es endlich richtig und nicht nur so ne Pseudoerweiterung wie MMX mit Pseudo Registern und dann ist diese Erweiterung nicht einmal richtig Kompatible zum normalen Code? Das sind ma vieleicht Knalltüten. Eine CPU bauen können dann aber nicht daran denken das wir keine 128Bit CPU's haben. Wir sind ja noch nicht einmal auf 64Bit umgestiegen.
Wieos müssen die Daten denn überhaupt auf 16Byte ausgerichtet sein? Es ist doch klar das man die SIMD-Register meist nur für 4 Floating Pointe Werte nutzt und nicht für ein 128Bit breites Datenwort.
-
DragonMaster schrieb:
Es ist doch eigentlich nur die Ausrichtung? Und dem Stack ist es doch egal ob ich für einen Parameter nun 4Byte pushe oder 16.
Das weis man ja, es ist ja in der Struktur Definiert. Aber nagut.Nein, das ist gar nicht egal. z.B:
__declspec(align(16)) struct A { char a; int c; }; struct B { char a; int c; }; struct B1 { char a; int c; };
Strukturen B1 und B sind equivalent, sizeof (B1) == sizeof (B). Strukturen A und B sind NICHT equivalent.
Und normalweise sizeof (B) == 5 (Intel32 byte-Ausrichtung) aber sizeof (A) > 5 (es ist 32 wenn ich mich nicht irre). Das ist ein grosser Unterschied! Du kannst A statt B by-value nicht passieren weil die Funktion nur auf 5-byte Struktur wartet.