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 と浮動小数演算最適化