Android 端末 ZEN Touch2 は低価格ながら i.MX51 を搭載しており
CPU core は ARM Cortex-A8 であることがわかりました。
ARMv7 アーキテクチャなので ARM11 (ARMv6) 系のスマートフォンより高速に
動作すると考えられます。
ところが ZENTouch2 は armeabi-v7a で build した NDK のアプリケーションを
インストールすることができませんでした。
armeabi なら OpenGL ES 2.0 を使っていても実行出来ることが分かっています。
●NDK とアーキテクチャ
現在の Android NDK r5 は 2つの ARM アーキテクチャに対応しています。
・armeabi ARMv5TE ・armeabi-v7a ARMv7
armeabi (ARMv5TE) と比べた場合 armeabi-v7a (ARMv7) のメリットは下記の通り。
・1. VFP (fpu) が使用可能。ハードウエアによる浮動小数演算
・2. Thumb-2 命令セット対応
・3. NEON (SIMD) 命令を利用可能。
・4. ARMv6 以降の新しい命令が使用可能。
4. でいえば、例えばスレッド間の同期に使う ldrex, strex 命令があります。
Compare And Swap 等のアトミック命令を作成できるので、これを使って
様々な同期オブジェクトを作ります。
Thumb-2 は Thumb 同様コード容量を抑えつつも、浮動小数演算など ARM (32bit)
相当の命令が利用出来るよう拡張されています。
特にメリットあるのは VFP/NEON かもしれません。
Android でも VFP 前提でネイティブなコードを書くことが可能となります。
●NDK と ARMv7 の浮動小数演算
NDK では armeabi-v7a (ARMv7) の場合少なくとも VFPv3-D16 対応であると
みなしています。
VFPv3 には 2つのバリエーションがあります。
・VFPv3-D16
・VFPv3-D32
VFPv3 は 32個の単精度浮動小数レジスタを持っています。
・単精度 32bit レジスタ s0~s31
・倍精度 64bit レジスタ d0~d15
+---------+---------+---------+- -+---------+ | d0 | d1 | d2 | | d15 | +----+----+----+----+----+----+ ~ +----+----+ | s0 | s1 | s2 | s3 | s4 | s5 | | s30| s31| +----+----+----+----+----+----+- -+----+----+
↑倍精度レジスタと単精度レジスタは上記のように共有されます。
倍精度レジスタは 16個ですがレジスタフィールドは 5bit あるため
命令上は倍精度レジスタを 2倍に増やすことが可能です。
+---------+---------+- -+---------+- -+---------+---------+ | d0 | d1 | | d15 | | d30 | d31 | +----+----+----+----+ ~ +----+----+ ~ -+---------+---------+ | s0 | s1 | s2 | s3 | | s30| s31| +----+----+----+----+- -+----+----+
↑このように倍精度レジスタを 2倍に増やしたのが VFPv3-D32 となります。
NEON 命令を実装している場合 128bit の SIMD レジスタが 16個あります。
レジスタは VFP と共有されるため、NEON 命令が使える CPU では自然に
VFPv3-D32 相当となります。
+-------------------+- -+-------------------+- -+-------------------+ | q0 | | q7 | | q15 | +---------+---------+ +---------+---------+ +---------+---------+ | d0 | d1 | ~ | d14 | d15 | ~ | d30 | d31 | +----+----+----+----+ +----+----+----+----+ -+---------+---------+ | s0 | s1 | s2 | s3 | | s28| s29| s30| s31| +----+----+----+----+- -+----+----+----+----+
よって Android NDK の場合は armeabi-v7a 選択時は下記の 2種類存在して
いることになります。
(1) VFP のみの場合は VFPv3-D16
(2) NEON 対応時の VFP は VFPv3-D32
実際に調べた結果は下記のとおり
(1) VFP のみ (VFPv3-D16)
・Tegra2 Cortex-A9 MPCore
(2) VFP+NEON (VFPv3-D32)
・Cortex-A8 各種
・Scorpion (Snapdragon)
●armeabi まとめ
abi arch 浮動小数 SIMD -------------------------------------------------- armeabi ARMv5TE なし なし armeabi-v7a ARMv7 VFPv3-D16 なし armeabi-v7a ARMv7 VFPv3-D32 NEON
armeabi と armeabi-v7a はバイナリを分けることが可能です。
両方のバイナリを含んでいる実行ファイルは fat binary と呼ばれているようです。
ARMv7 時に NEON 命令対応かどうかの判定は x86 の SSE のように実行時に行います。
●abi の指定方法
NDK を使ったコードは、プロジェクトの jni フォルダに配置します。
ここに c/cpp コードと Android.mk を置いて NDK 付属の ndk-build コマンドを
実行します。
例えば NDK 付属サンプルをビルドするなら下記のように実行します。
(Windows + cygwin 利用時に NDK を c:/sdk/android-ndk-r5 に展開したと仮定)
$ cd /cygdrive/c/sdk/android-ndk-r5 $ cd samples/hello-gl2 $ ../../ndk-build
armeabi-v7a を指定するには下記のようにします。
$ ../../ndk-build TARGET_ARCH_ABI=armeabi-v7a
jni フォルダに Application.mk を作成し、下記の 1行を書いておけば
無指定でも armeabi-v7a になります。
# Application.mk APP_ABI := armeabi-v7a
下記のように記述すれば両対応の fat binary になります。
# Application.mk APP_ABI := armeabi armeabi-v7a
NEON 対応で build するには Android.mk に “LOCAL_ARM_NEON := true” を加えます。
Windows 上の cygwin 経由だと make が遅いので、自分で build system を
構築するのもありかもしれません。
●互換性
ARMv7 アーキテクチャの端末でも ARMv5TE の armeabi のバイナリを実行できます。
上位互換性が保たれています。
1. もし armeabi-v7a の lib があればそれを使う。
2. なければ armeabi の lib を読み込む。
ARM11 のように ARMv6 アーキテクチャの場合は常に armeabi (ARMv5TE) が
選択されます。残念ながら ARMv6 の命令や機能は利用できません。
例えば ARM11 の CPU Core で VFP を搭載していたとしても VFP 命令を
活用できないことになります。
同じ ARM11 で比べた場合、c/cpp コード移植時は VFP が使える iOS の方が
高速に動作する可能性があります。
ただしこれはあくまで Android の NDK を使ったアプリケーションの話です。
カーネルや Java コードが ARMv6/VFP の機能を活用していないわけではありません。
●CPU Features
NDK には ARMv7 向けに NEON 対応などの CPU Feature を判定するコードが
付属しています。
ソースを見ると、単に /proc/cpuinfo を読み出して Features の行を見ているだけ
であることがわかります。
“vfp” や “neon” といった文字列そのもので判断しています。
●ZEN Touch2
ZEN Touch2 は Cortex-A8 搭載ですが cpuinfo の Features に “vfp” は
あるものの “neon” が含まれていません。
同じ i.MX51 を搭載している NetWalker も全く同様で “neon” がありませんが
NEON 命令をコンパイルすると実行することが出来ます。
(過去のエントリ参照)
よって ZEN Touch 2 も NEON 命令自体には対応していると考えられます。
Features に “neon” が含まれていないのは i.MX51 の何らかの事情によるもの
でしょうか。
また ZENTouch2 で armeabi-v7a のバイナリを install 出来ない理由も
分かっていません。
関連エントリ
・Android ZEN Touch 2 の CPU/GPU その2
・Creative ZiiO 7 ZMS-08 GPU と OpenGL ES 2.0
・Tegra2 Cortex-A9 と浮動小数演算
・Snapdragon と浮動小数演算速度
・ARM Cortex-A8 の NEON と浮動小数演算最適化
・NetWalker PC-Z1 Cortex-A8 (ARM) 浮動小数演算の実行速度