ARMv7 の fpu、vfp には大きく分けて NEON 命令のありなしで 2種類あります。
細かい違いを含めると更に増えます。
gcc のオプションを見るとこんな感じ。
vfp vfpv3 vfpv3-d16 vfpv3-fp16 vfpv3-d16-fp16 neon neon-fp16 vfpv4 vfpv4-d16 neon-vfpv4
使える機能はハードウエアレジスタ MVFR0/MVFR1 を見ることで判断できる
ようです。分かる範囲でまとめてみました。
D32 VSP VDP DIV SQR SV NLS NI NSP NHP VHP FMA
--------------------------------------------------------------------
Cortex-A8 vfpv3+NEON ◎ ◎ ◎ ◎ ◎ ◎ ◎ ◎ ◎ -- -- --
Cortex-A9 vfpv3-D16 -- ◎ ◎ ◎ ◎ ◎ -- -- -- -- ◎ --
Cortex-A9 vfpv3+NEON ◎ ◎ ◎ ◎ ◎ -- ◎ ◎ ◎ ◎ ◎ --
Cortex-A5 vfpv4-D16 -- ◎ ◎ ◎ ◎ -- - -- -- - ◎ ◎
Cortex-A5 vfpv4+NEON ◎ ◎ ◎ ◎ ◎ -- ◎ ◎ ◎ ◎ ◎ ◎
--------------------------------------------------------------------
D32 = double 32個
VSP = VFP 単精度演算
VDP = VFP 倍精度演算
DIV = HW 除算
SQR = HW 平方根
SV = VFP Short Vector 対応
NLS = NEON Load/Store
NI = NEON Int演算
NSP = NEON 単精度演算
NHP = NEON half(fp16) 演算
VHP = VFP half(fp16) 演算
FMA = IEEE 積和 Fused Multiply Add
Cortex-A9 以降は fp16 (16bit 浮動小数点命令) に対応しています。
vfpv3 と vfpv4 の違いは FMA (Fused Multiply Add) にあるようです。
また VFP の Vector Mode (SV) が Cortex-A9 の NEON 版から無くなっている
こともわかります。この場合 FPSCR の Len が 0 以外の場合例外が発生し、
ソフトウエアでエミュレーションすることになるようです。
Cortex-A9 で fp16 命令を試してみました。
下記の命令で 16bit, 32bit float の相互変換ができます。
vcvtb.f16.f32 sd, ss vcvtt.f16.f32 sd, ss vcvtb.f32.f16 sd, ss vcvtt.f32.f16 sd, ss
Android NDK ではオプション指定してもコンパイルできませんでしたが、
iOS ではコンパイルが通りました。
unsigned int SingleToHalf( float a, float b )
{
float fparam[4];
fparam[0]= a;
fparam[1]= b;
__asm__ __volatile__(
"vldmia %0, {d0-d1}\n"
"vcvtb.f16.f32 s2, s0\n"
"vcvtt.f16.f32 s2, s1\n"
"vstmia %0, {d0-d1}\n"
: "=&r"( fparam )
: "0"( fparam )
: "d0","d1","cc" );
unsigned int* iparam= (unsigned int*)fparam;
return iparam[2];
}
void HalfToSingle( unsigned int param_in )
{
unsigned int iparam[4];
iparam[0]= param_in;
__asm__ __volatile__(
"vldmia %0, {d0-d1}\n"
"vcvtb.f32.f16 s1, s0\n"
"vcvtt.f32.f16 s2, s0\n"
"vstmia %0, {d0-d1}\n"
: "=&r"( iparam )
: "0"( iparam )
: "d0","d1","cc" );
float* fparam= (float*)iparam;
printf( "%f %f\n", fparam[0], fparam[1] );
}
iPad2 (Cortex-A9) で動作し、相互変換できました。
fp16 未対応の iPod touch 3 (Cortex-A8) ではエラーで停止します。
PowerVR SGX, Adreno, Tegra2 など 16bit (half) float 対応の GPU は
意外に多いので、頂点フォーマットの変換に使いたい機能です。
関連エントリ
・Snapdragon の本当の浮動小数点演算能力
・iPad2 A5 と浮動小数演算 VFP/NEON
・Tegra2 Cortex-A9 と浮動小数演算
・Snapdragon と浮動小数演算速度
・ARM Cortex-A8 の NEON と浮動小数演算最適化