2013-02-23 17 views
10

Betrachten Sie diese Variablendeklaration:Zugriff auf Bytes einer __m128-Variablen über Union Legal?

union { 
     struct { 
      float x, y, z, padding; 
     } components; 
     __m128 sse; 
    } _data; 

Meine Idee ist es, den Wert durch x, y, z Felder zuweisen, SSE2 Berechnungen durchführen und das Ergebnis durch x, y, z zu lesen. Ich habe jedoch leichte Zweifel, ob es legal ist. Meine Sorge ist Ausrichtung: MSDN sagt, dass __m128 Variablen automatisch auf 16-Byte-Grenze ausgerichtet sind, und ich frage mich, ob meine Vereinigung dieses Verhalten brechen kann. Gibt es hier noch andere Probleme?

+0

Nein, die Ausrichtung ist kein Problem. Die Gewerkschaft wird jede Ausrichtung haben, die notwendig ist, damit alle ihre Mitglieder korrekt arbeiten können. –

+2

Beachten Sie auch, dass Sie zumindest in Visual Studio die Komponenten von '__m128 sse;' mit 'sse.m128_f32 [0]', 'sse.m128_f32 [1]', 'sse.m128_f32 [2]', 'sse.m128_f32 [3]', also gibt es keinen Grund für diesen Trick. –

+0

@ R.MartinhoFernandes und für gcc? –

Antwort

6

Die Ausrichtung der Verbindung sollte in Ordnung sein, aber im Fall von Windows können Sie möglicherweise direkt auf die 32-Bit-Komponenten zugreifen. Von xmmintrin.h (DirectXMath):

typedef union __declspec(intrin_type) _CRT_ALIGN(16) __m128 { 
    float    m128_f32[4]; 
    unsigned __int64 m128_u64[2]; 
    __int8    m128_i8[16]; 
    __int16    m128_i16[8]; 
    __int32    m128_i32[4]; 
    __int64    m128_i64[2]; 
    unsigned __int8  m128_u8[16]; 
    unsigned __int16 m128_u16[8]; 
    unsigned __int32 m128_u32[4]; 
} __m128; 

Wie Sie sehen können, gibt es vier Schwimmer drin. Wenn Sie über paranoid sein wollen, können Sie wahrscheinlich alle die gleichen Ausrichtung Spezialitäten und so definieren, um sicherzustellen, dass nichts bricht. Soweit ich jedoch sehen kann, und da Sie MSDN in Ihrer Antwort erwähnt haben, sollten Sie alle gut gehen. Sowohl die Verbindung als auch der Zugriff darauf sollten funktionieren, wenn Sie wissen, dass Sie SSE-kompatibles Zeug haben. Sie können auch die DirectXMath-Header durchsuchen, um ein Gefühl dafür zu bekommen, wie Windows die Definitionen ausführt und sich selbst widerspricht: Sie definieren auch ein paar Makros, abhängig davon, welche Eigenschaften und Fähigkeiten zur Kompilierungszeit vorhanden sind.

EDIT: Wie der R.MartinhoFernandes in den Kommentaren sagt, ist der direkte Zugriff wahrscheinlich viel weniger Kopfschmerzen, als es in einer Union neu zu definieren.

+1

Ich wollte meine Code-Teile plattformübergreifend behalten, daher der Union-Trick. –

+0

@VioletGiraffe Dann sollte die Vereinigung gut gehen. GCC sollte auch die Gewerkschaft respektieren und auch nichts Unkonventionelles tun, aber ich bin kein GCC-Experte und ich bin mir sicher, dass ein Jurist aus Standarde mitkommen wird und uns beide zu den tiefsten Höllen verdammt, wenn er "Gewerkschaft" benutzt. –