色々思惑があって買ったNexus9。ようやくUVCカメラアプリも大きな問題なく動くようになったのでテストを兼ねてAMMv8-64ビット向けにビルドしたのと従来通りのARM/ARMv7a(32ビット)向けにビルドしたのを実行して比べて見たよ。
使ったのはUVCカメラをAndroidで使うためのアプリ、UsbWebCameraProです。現在Google Playで公開しているバージョンはバックエンドにlibusb/libuvcを使っていましたが、今回テストしたのはAndroid5.0対応のためにC++で作ったオレオレライブラリ版です。
わずかに条件コンパイルで分けている部分(ログ出力用の部分です)はあるものの基本的には同じソースをAPP_ABI := armeabi/armeabi-v7a/arm64-v8aでビルドした場合の比較です。
なおarmeabiでコンパイルした場合でもCPUがサポートしていればNEONが有効になるようにしているので、今回のテスト結果ではarmeabiでコンパイルした場合を含めて全てNEONを使用した結果と言うことになります。簡易的な測定なので測定自体の時間も含んでいますが、いずれの条件でも1ミリ秒/フレーム以下です。
また、元々入れてた最適化設定は一部arm64-v8aではサポートされてないのがあって警告が出てますがそのままにしてます。
条件は、1920×1080@30fps設定で取得したMJPEGの映像フレームをlinjpeg-turboでデコードしてGPUで
ピクセルフォーマット変換しながらレンダリングした時の1フレームの当たりの処理時間を簡易的に測定しています。測定時間は約3分で2000〜6000フレーム分の平均値になります。映像ソースは以前のNEONの有無による処理速度への影響を確認した時と同じWiiUのHDMI出力をFEBON168フレームグラバーでキャプチャしています。
と言う事で結果です。
グラフ中の値はNexus5(Android4.4.4, Dalvik, amrabi-v7a)での値を100%とした時の相対値になります。
NaitiveコードでのMJPEG展開・描画なのでアンドロイドのランタイムの差はほぼ無いと見ていいでしょうね。
しかしあれまぁ〜ARM64-v8aでコンパイルした方が遅くなってしまいました。ポインタやサイズ指定していないint/unsigned intのビット長が長くなってアクセス時間が増えたのかあるいはコンパイラの出力コードの質がまだ低いのか、あるいは外部メモリバス幅が32ビットのままなのかとか色々考えられますが・・・いずれにしても単純にビルドし直すだけだと性能は活かせてないみたいですね。メモリ空間が大きくなるメリットを享受できるアプリでもありませんし。
今の時点では高速なARMv7aと思ったほうがよろしいかと。コンパイラの進歩に期待しましょう。
今回の結果から当面はARM64-v8a向けのバイナリは無しで行きたいと思います。
ちなみに、裏で動いているUSB通信処理のスレッドの方が優先度を高くしていますし少なくても1ミリ秒に数回以上のUSB通信処理が割り込んでくるので端末のCPU性能の全てをJPEG展開・描画につぎ込んでいるわけではありません。またメインスレッド+通信2スレッド+描画関係が2スレッド+その他でアプリ内だけでも6スレッド以上並列実行になっています。K1はデュアルコアなのに対してNexus5はクワッドコアなので、CPU自体のシングルスレッドの性能差ほどには差異が出にくく、ベンチマークアプリ等での結果と異なるかもしれませんがあしからず。
ところで、実際に動かしてみてもそうですし、こうやって数字にすると尚更ですがNexus7(2012)はNexus9と比べると3.5倍以上の差を付けられてしまいました。普通のアプリならそこそこ快適に使える機種ですが今回のようなCPU/GPUをゴリゴリ使うようなアプリではだんだん厳しくなってきましたね。
と言う事でお疲れ様でした。(^_^)/~