__m128
読み:アンダースコア-アンダースコア-エムひゃくにじゅうはち
外語:__m128

 x86プロセッサー用のC/C++で、SSEを扱うための独自のデータ型(変数型)。SSE2以降では関連して__m128iと__m128dが追加された。
目次

定義
 #include <xmmintrin.h>
 #include <emmintrin.h>
 #include <pmmintrin.h>
 SSEはxmmintrin、SSE2の機能を使うためにはemmintrin、SSE3の機能はpmmintrinをincludeすることで、それぞれ利用可能になる。

概要
 SSEで使うXMMレジスターは、128ビット長のSIMD演算装置用レジスターである(Intel AVX以降は256ビットのYMMレジスターに拡張された)。
 通常のintやlongなどと性質の異なるものであり、SSEで使われるレジスター幅の変数を定義するため、このような独自の型が用意された。
 当然、SSEなどと無縁の環境に対する移植性はないものの、Microsoft WindowsPC UNIX(FreeBSDLinux等)では共通して使えるようである。

特徴

仕様

Windows
 Microsoft Visual Studio 2010の場合、次のように定義がある。
 xmmintrin.h
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;
 emmintrin.h
typedef union __declspec(intrin_type) _CRT_ALIGN(16) __m128i {
    __int8              m128i_i8[16];
    __int16             m128i_i16[8];
    __int32             m128i_i32[4];
    __int64             m128i_i64[2];
    unsigned __int8     m128i_u8[16];
    unsigned __int16    m128i_u16[8];
    unsigned __int32    m128i_u32[4];
    unsigned __int64    m128i_u64[2];
} __m128i;
typedef struct __declspec(intrin_type) _CRT_ALIGN(16) __m128d {
    double              m128d_f64[2];
} __m128d;
 Cの標準機能のみで定義することができないため、Visual C/C++の独自拡張機能を用いて定義されているが、その実体はどうやらunionのようである。

FreeBSD
 FreeBSDの場合、次のように定義がある。
 xmmintrin.h
 typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
 emmintrin.h
 typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
 typedef double __m128d __attribute__ ((__vector_size__ (16), __may_alias__));
 Cの標準機能のみで定義することができないため、GCCの独自拡張機能を用いて定義されている。
 __vector_size__は、バイト単位で変数のベクトル長を定義するものである。ここでは16バイト(つまり128ビット)である。__m128型はパックド単精度浮動小数点に、__m128d型はパックド倍精度浮動小数点に、__m128i型はパックド整数にそれぞれ対応しており、例えば__m128のfloat型なら、各32ビット長、つまり4バイト4台のベクトルとして定義される。
 __may_alias__は、この属性を持つ型のオブジェクトへのアクセスは、型に基づく別名解析の対象とされず、代わりにchar型と同様、他の種類のオブジェクトへの別名として定義される。

利用方法
 __m128は、関数の戻り値やパラメーターとして利用できるが、他の一般的な算術式と共に使うことはできない。
 処理系の実装に依存するが、この変数型を扱うための関数が用意されており、これを通してSSEを使うことになる。
 なお、Intel AVX以降で拡張された256ビットのYMMレジスターは、__m256、__m256d、__m256i、のいずれかで扱うことができる。
 結果として、__m128データ型は4つの32ビット浮動小数点数、__m128dデータ型は2つの64ビット浮動小数点数、__m128iデータ型は16個の8ビット整数値、8個の16ビット整数値、4個の32ビット整数値、または2個の64ビット整数値を保持することができる。

再検索