Novo 7 Paladin は MIPS CPU で Android 4.0 を搭載した端末です。
RenderScript を試してみました。
前回の記事で触れたように、mips 対応版 NDK を入れると対応
アーキテクチャが一気に 6種類に増えます。
さらに armeabi-v7a や mips-r2 の NDK では、ハードウエアの性能を
引き出すために CPU のオプション機能を利用することができます。
ただし搭載していないハードもあるため事前に CPU Features を
チェックしなければなりません。
下記は NDK の cpu-features が返す値です。
armeabi-v7a: ANDROID_CPU_ARM_FEATURE_ARMv7 ANDROID_CPU_ARM_FEATURE_VFPv3 ANDROID_CPU_ARM_FEATURE_NEON mips-r2: ANDROID_CPU_MIPS_FEATURE_R2 ANDROID_CPU_MIPS_FEATURE_DSP ANDROID_CPU_MIPS_FEATURE_DSP_R2
種類が増えてくると個別最適化は困難となりますし、ビルドや
テストの手間もかかります。
こんな場合 CPU 非依存で Native 相当の実力を持つ RenderScript は
検討する価値がありそうです。
・Android 4.0 対応、RenderScript のサンプル
上の記事に掲載したサンプルは MIPS の Paladin でも動作しました。
ただし一部修正が必要でした。
Android 3.x (API 11~13) をターゲットにビルドした RenderScript の
アプリケーションは実行時に下記のようなエラーが出ます。
Could not parse bitcode file Failed to translate bitcode from version: 11
RenderScript の byte code (bitcode) は Android 3.x (API 11~13)
と Android 4.0 以上 (API 14 以降) で互換性が無いようです。
そのため API Level 14 以上を target にして再コンパイルする
必要があります。
(1) SdkVersion を 14 以上にする
AndroidManifest.xml の SdkVersion を 11 から 14 に修正します。
↓
もし同じフォルダに project.properties ファイルが作られているなら
target=android-15 (または 14) に書き換えます。
(2) rsForEach() を API 14 以降の書式に変更
上のページで紹介したプログラムでは必要ありませんが、Android
SDK 付属の RenderScript サンプルを走らせる場合は必要です。
API 14 以降は rsForEach() の引数が書式が変更されているので、
rsForEach() でコンパイルエラーが出たら引数最後の 0 を削除します。
(3) bc ファイルを作りなおす
bc ファイルを作りなおすためにプロジェクトを一旦 Clean してから
ビルドし直します。
Eclipse の場合はプロジェクトを選択して Menu Project → Clean…
これで Paladin (MIPS + Android 4.0) 上で RenderScript の
プログラムが動くようになります。
描画はそこそこですが CL 系は遅いです。
CPU が Single core であることに加え、浮動小数点演算もあまり
速くないようです。
●実行速度比較(1)
まずは Linpack for Android v1.2.8 で比較してみました
Single Multi MFLOPS MFLOPS OS CPU ---------------------------------------------------------------------- 18.091 -- 2.3 Cortex-A8 1.0GHz S5PC110 Galaxy S SC-02B 18.592 -- 4.0 MIPS XBurst 1.0GHz JZ4770 Novo7 Paladin 35.628 -- 2.2 Scorpion 1.0GHz QSD8250 Desire X06HT 30.33 57.233 3.1 Cortex-A9 x2 1.0GHz Tegra2 Optimus Pad L-06C 46.164 74.664 2.3 Scorpion x2 1.2GHz MSM8660 EVO 3D ISW12HT 57.342 92.981 2.3 Cortex-A9 x2 1.2GHz Exynos4210 Galaxy S2 SC-02C 47.071 140.908 3.2 Cortex-A9 x4 1.3GHz Tegra3 EeePad TF201 * MFLOS の数値が大きい方が速い。 * Single = Single-Thread * Multi = Multi-Thread
Multi Thread はタイミングによるばらつきが大きいため何度か
実行し最速の数値を取っています。あまり正確でないかもしれませんし、
単精度ではまた違った結果になると思います。
取り敢えず Paladin の fpu は激遅の Cortex-A8 VFP に近い速度
ということがわかりました。
●実行速度比較(2)
RenderScript, Java, NDK C, NDK asm の演算比較。
4×4 Matrix * Vector の 50万回。(1)~(13) すべて同じ演算。
Paladin GS Desire Tegra2 GS2 GN Tegra3 XBurst A8 Scorpion A9x2 A9x2 A9x2 A9x4 1.0GHz 1.0GHz 1.0GHz 1.0GHz 1.2GHz 1.2GHz 1.3GHz ------------------------------------------------------------------------ (1) RenderScript A 290 -- -- 52 -- 29 57 (2) RenderScript B 314 -- -- 69 -- 44 62 (3) RenderScript C 310 -- -- 51 -- 31 37 (4) Java Inline 482 698 418 244 179 174 167 (5) Java Matrix 11763 1012 1906 1232 1127 4785 840 (6) NDK (C func) 158 166 60 79 39 39 43 (7) NDK C inline1 267 288 49 66 43 33 41 (8) NDK C inline2 243 289 54 65 46 32 41 (9) NDK asm VFP -- 139 35 46 22 19 35 (10)NDK asm VFP MT2 -- 139 37 26 14 15 48 (11)NDK C NEON Intrin -- 26 33 -- 26 21 34 (12)NDK asm NEON -- 20 23 -- 38 18 32 (13)NDK asm NEON MT2 -- 22 29 -- 26 17 17 実行時間(msec) 数値が小さいほうが速い。 * GS=Galaxy S SC-02B, GS2=Galaxy S2 SC-02C, GN=Galaxy Nexus SC-04D * Tegra2= Optimus Pad L-06C, Tegra3= EeePad TF201 * A8= Cortex-A8, A9= Cortex-A9 * Intrin= Intrinsic (Builtin Function) * MT2= Multi thread x2
速いデバイスほど実行時間が短く誤差が出ます。
また演算命令が高速になるほどメモリアクセス速度の影響が増えます。
マルチスレッド実行の場合スレッドの起動や同期によるばらつきが大きく
あまり正確ではありません。
RenderScript の演算では Paladin は A9 dual と 5~10倍くらいの
差が生じていることがわかります。
Paladin の fpu 自体は Cortex-A8 VFP より若干高速です。
ただし、Cortex-A8 も NEON を使うと数倍高速であり、A9 の速度に
ほとんど追い付いています。
Scorpion/A9 になると VFP/NEON 共に安定して速度が出ています。
注意点としてはJava の実行時間には GC が含まれている可能性があります。
また最高でも 2 Thread しか使っていないので Tegra3 は最速ケースでは
ありません。
関連エントリ
・Android 4.0 ainol Novo 7 Paladin、MIPS CPU の NDK と Vivante GPU
・Android 4.0 対応、RenderScript のサンプル
・Android 3.x RenderScript (1)
・Snapdragon の本当の浮動小数点演算能力
・ARM Cortex-A8 の NEON と浮動小数演算最適化
うわぁ、遅いですね。Java Matrixなど1桁違っています。
Cでの性能を考えるとやはりdalvikのチューニングがまだまだということでしょうか。
私のプログラムが遅いのも納得です。