__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 WindowsとPC UNIX(FreeBSDやLinux等)では共通して使えるようである。
特徴
仕様
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ビット整数値を保持することができる。
再検索