11

次の変数宣言を検討してください。

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

x私の考えは、、、フィールドを介して値を割り当て、ySSE2計算を実行し、、、を介して結果を読み取ることです。ただし、合法かどうかについては少し疑問があります。私の懸念はアラインメントです: MSDN によると、変数は自動的に 16 バイト境界にアラインされます。ここで考慮すべき他の落とし穴はありますか?zxyz__m128

4

1 に答える 1

5

ユニオンの配置は問題ないはずですが、Windows の場合は 32 ビット コンポーネントに直接アクセスできる場合があります。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;

ご覧のとおり、そこには 4 つのフロートがあります。超偏執的になりたい場合は、おそらくすべて同じ属性の特殊性などを定義して、何も壊れないようにすることができます. ただし、私が見る限り、回答で MSDN について言及したことを考えると、問題はありません。SSE互換のものがあることがわかっている場合、ユニオンとそれに直接アクセスすることの両方が機能するはずです。DirectXMath ヘッダーを調べて、Windows が定義とラングリング自体をどのように行っているかを把握することもできます。それらは、コンパイル時に存在する組み込み関数と機能に応じて、いくつかのマクロも定義します。

編集: R.MartinhoFernandes がコメントで述べているように、直接アクセスすることは、ユニオンで再定義するよりもおそらく頭痛の種ではありません。

于 2013-02-23T20:24:07.293 に答える