Android SDKのQEMUでArmv7対応

ちょっと調べたいことがあって、masterツリーでビルドしてみたら、

  • TARGET_ARCH_VARIANT=armv7-a

になってて驚いた。ソースコードレビューを見てみると、

ということらしい。QEMUのパッチは

で取り込まれていたので、ビルドしてみて遊んだ。

$ cd master
$ repo sync -j4
$ source build/envsetup.sh
$ lunch full-eng
$ time make -j8

蛇足だけど、repo syncも-jで並列できる。ビルドしたバイナリファイルのアーキテクチャを確認。

$ prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-readelf \
  -A \
  out/target/product/generic/system/bin/dalvikvm
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM v7"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_VFP_arch: VFPv3
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP

ビルドしたエミュレータを起動。$ANDROID_PRODUCT_OUTがlunchで設定されているので、引数なしで起動できる。

$ out/host/linux-x86/bin/emulator -wipe-data &

起動したらadbで覗いてみる。

$ adb shell cat /proc/cpuinfo
Processor       : ARMv7 Processor rev 0 (v7l)
BogoMIPS        : 331.77
Features        : swp half thumb fastmult vfp edsp neon vfpv3 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc08
CPU revision    : 0

Hardware        : Goldfish
Revision        : 0000
Serial          : 0000000000000000

ところで、現在のmasterツリーでビルドしたemulatorのbrowserは起動できない。Building MLにパッチがあるが、レビュー中のパッチをcherry pickしてみる。

$ cd bionic
$ git fetch git://android.git.kernel.org/platform/bionic \
  refs/changes/94/23894/3 && git checkout FETCH_HEAD
$ cd ..
$ time make -j8

QEMUパッチのコメントによると、emulatorの起動時間が短くなったらしいので、計測してみた。emulatorコマンドをンッターーーンッ!してからホーム画面が表示されるまでの時間。

tree 初回起動 2度目の起動
master 1:19 0:27
gingerbread 1:54 0:39

多少、早くなることが期待できる。あと、/proc/cpuinfoにあるとおり、NEONのエミュレーションにも対応しているが、愚直にx86コードへトランスレートしているだけなので遅くなるらしい。試してみた。TARGET_ARCH_VARIANTをexportで変更してもlunchの方が優先されるらしく、BoardConfig.mkを直接変更した。

 --- a/target/board/generic/BoardConfig.mk
 +++ b/target/board/generic/BoardConfig.mk
 @@ -18,7 +18,7 @@ TARGET_NO_KERNEL := true
  # that are slower to emulate. On the other hand, it is possible to emulate
  # application code generated with the NDK that uses NEON in the emulator.
  #
 -TARGET_ARCH_VARIANT := armv7-a
 +TARGET_ARCH_VARIANT := armv7-a-neon
  TARGET_CPU_ABI := armeabi-v7a
  TARGET_CPU_ABI2 := armeabi

まずはバイナリのアーキテクチャをチェック。

$ prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-readelf \
  -A \
 out/target/product/generic/system/bin/dalvikvm 
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM v7"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_VFP_arch: VFPv3
  Tag_NEON_arch: NEONv1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP

$  prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-readelf \
   -A \
   out/target/product/generic/system/lib/libjpeg.so 
Attribute Section: aeabi
File Attributes
  Tag_CPU_name: "ARM v7"
  Tag_CPU_arch: v7
  Tag_CPU_arch_profile: Application
  Tag_ARM_ISA_use: Yes
  Tag_THUMB_ISA_use: Thumb-2
  Tag_VFP_arch: VFPv3
  Tag_NEON_arch: NEONv1
  Tag_ABI_PCS_wchar_t: 4
  Tag_ABI_FP_denormal: Needed
  Tag_ABI_FP_exceptions: Needed
  Tag_ABI_FP_number_model: IEEE 754
  Tag_ABI_align8_needed: Yes
  Tag_ABI_enum_size: int
  Tag_ABI_HardFP_use: SP and DP

そして、動かしてみた。

tree neon Sprite Text Neocore
master off 55fps 4.1fps
master on 55fps 4.3fps
gingerbread n/a 30fps 3.2fps

あれ?速くなってるし。なぞゆえ。gingerbreadよりmasterの方が速いのはこのところ少しずつ追加されているOpenGLトランスコードの効果らしい。関係ないと思われるが起動時間も。

tree 初回起動 2度目の起動
master-neon 1:17 0:30

QEMUのArmv7対応はもう1つOSSらしい点がある。パッチのコメントにあるのだが、

  • upstreamはMeeGo
  • NEON対応はLinaroの成果

を取り入れていて、今後も相乗効果が期待できる。