十五年测试老手,长期负责WEB\APP 项目测试,目前主要负责团队管理工作。

Android性能测试工具

上一篇 / 下一篇  2011-09-16 21:48:17 / 个人分类:Android

文章来源
  • 文章来源:【转载】
Android应用的性能如何测试?JAVA层面可以用TraceView,可是用NDK开发出来的是so,TraceView跟踪不了怎么办?问了Google大神,答案是OProfile! 
Oprofile 是Linux系统下一个低开销的系统全局的性能监视工具,利用处理器上所包含的专用的性能监视硬件(若没有性能监视硬件则使用一个基于计时器的代用品)来收集与性能相关的数据样品。它获得关于内核以及系统上的可执行文件的信息,例如内存是何时被引用的;L2缓存请求的数量;收到的硬件中断数量等。 
Oprofile的特点如下: 
l         无需重新编译源代码,如果不进行源代码及分析,连调试信息(-g option to gcc)也不是必须的。 
l         只在内核中插入一个模块。 
l         可以分析运行于系统之上的所有代码(禁用中断的代码除外) 
l         系统的额外开销小,Oprofile会增加1%-8%的系统开销(取决于采样频率) 
l         兼容所有2.2,2.4,2.6内核,可以运行在SMP系统之上 
l         支持主流CPU架构,包括X86、arm、AVR32、mips、powerpc等 
Oprofile要想跑在Andorid上,要满足下面的条件: 
1.内核要支持 
2.要将Oprofile移植到Arm平台上 


下面是移植的全过程: 
一、Oprofile移植 
用到的交叉编译工具如下: 
arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 
用到的库如下: 
popt-1.14.tar.gz 
binutils-2.21.tar.gz 
oprofile-0.9.6.tar.gz 


$ tar xvfz arm-2010.09-50-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C ~/ 
修改~/.bashrc,添加 
export PATH=${PATH}:/home/louieli/arm-2010.09/bin 


$ tar zxvf popt-1.14.tar.gz 
$ cd popt-1.14 
$ ac_cv_va_copy=yes ./configure --with-kernel-support --host=arm-none-linux-gnueabi --prefix=/home/louieli/work/popt 
$ make 
$ make install 


$ tar zxvf binutils-2.21.tar.gz 
$ cd binutils-2.21/ 
$ ./configure --with-kernel-support --host=arm-none-linux-gnueabi --prefix=/home/louieli/work/binutils --enable-shared 
$ make LDFLAGS="-all-static" 
可能会出现 cc1: warnings being treated as errors,找到出错文件的Makefile文件,将-Werror去掉 
$ make install 


$ tar zxvf oprofile-0.9.6.tar.gz 
$ cd oprofile-0.9.6/ 
$ ./configure --with-kernel-support --host=arm-none-linux-gnueabi --prefix=/home/louieli/work/oprofile/ --with-extra-libs=/home/louieli/work/popt/lib/ --with-extra-includes=/home/louieli/work/popt/include/ --with-binutils=/home/louieli/work/binutils 
$ make LDFLAGS="-all-static -L/home/louieli/work/binutils/lib -Xlinker -R -Xlinker /home/louieli/work/binutils/lib  -L/home/louieli/work/popt/lib/" 
$ make install 
用file 命令查看,我们需要的oprofile文件都已经变成可以在android上跑的静态链接文件了 
install.sh: Bourne-Again shell script. text executable 
opannotate: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped 
oparchive:  ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped 
opcontrol:  a /system/bin/sh script. text executable 
opgprof:    ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
ophelp:     ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
opimport:   ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped 
opjitconv:  ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped
opreport:   ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped 
oprofiled:  ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, for GNU/Linux 2.6.16, not stripped




二、编译linux内核映像 
a)准备交叉编译工具链 
android代码树中有一个prebuilt项目,包含了我们编译内核所需的交叉编译工具。 


b)设定环境变量 
$ emacs ~/.bashrc 
增加如下两行: 
export PATH=$PATH:~/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin 
export ARCH=arm 
保存后,同步变化: 
$ source ~/.bashrc 


c)获得合适的内核源代码 
$ cd ~/android 
获得内核源代码仓库 
$ git clone git://android.git.kernel.org/kernel/common.git kernel 
$ cd kernel 
$ git branch 
显示 
* android-2.6.27 
说明你现在在android-2.6.27这个分支上,也是kernel/common.git的默认主分支。 
显示所有head分支: 
$ git branch -a 
显示 
* android-2.6.27 
remotes/origin/HEAD -> origin/android-2.6.27 
remotes/origin/android-2.6.25 
remotes/origin/android-2.6.27 
remotes/origin/android-2.6.29 
remotes/origin/android-goldfish-2.6.27 
remotes/origin/android-goldfish-2.6.29 
我们选取最新的android-goldfish-2.6.29,其中goldfish是android的模拟器模拟的CPU。 
$ git checkout -b android-goldfish-2.6.29 origin/android-goldfish-2.6.29 
$ git branch 
显示 
android-2.6.27 
* android-goldfish-2.6.29 
我们已经工作在android-goldfish-2.6.29分支上了。 


d)设定交叉编译参数 
打开kernel目录下的Makefile文件,把CROSS_COMPILE指向刚才下载的prebuilt中的arm-eabi编译器 
CROSS_COMPILE ?= arm-eabi- 
把 
LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\ 
$(call ld-option, -Wl$(comma)–build-id,)) 
这一行注释掉,并且添加一个空的LDFLAGS_BUILD_ID定义,如下: 
LDFLAGS_BUILD_ID = 


e)编译内核映像 
$ cd ~/android/kernel 
$ make goldfish_defconfig 
$ make menuconfig 
修改内核配置如下 
General setup --->
  • Profiling support (EXPERIMENTAL)[ ] Activate markers
  • OProfile system profiling (EXPERIMENTAL)这是把OProfile直接编进内核,也可以选择[M] OProfile system profiling (EXPERIMENTAL)会在arch/arm/oprofile文件夹下生成oprofile.ko,oprofile.ko需要用insmod载入。 
    $make 


    f)测试生成的内核映像 
    $ emulator -avd myavd -kernel ~/android/kernel/arch/arm/boot/zImage 


    三、Oprofile在android模拟器中的使用 
    1.先看一下opcontrol的参数 
    # opcontrol 
    opcontrol: usage: 
       -l/--list-events list event types and unit masks 
       -?/--help        this message 
       -v/--version     show version 
       --init           loads the oprofile module and oprofilefs 
       --setup          give setup arguments (may be omitted) 
       --status         show configuration 
       --start-daemon   start daemon without starting profiling 
       -s/--start       start data collection 
       -d/--dump        flush the collected profiling data 
       -t/--stop        stop data collection 
       -h/--shutdown    stop data collection and kill daemon 
       -V/--verbose[=all,sfile,arcs,samples,module,misc,ext] 
                        be verbose in the daemon log 
       --reset          clears out data from current session 
       --save=name      save data from current session to session_name 
       --deinit         unload the oprofile module and oprofilefs 
       -e/--event=eventspec 
          Choose an event. May be specified multiple times. Of the form 
          "default" or "name:count:unitmask:kernel:user", where : 
          name:     event name, e.g. CPU_CLK_UNHALTED or RTC_INTERRUPTS 
          count:    reset counter value e.g. 100000 
          unitmask: hardware unit mask e.g. 0x0f 
          kernel:   whether to profile kernel: 0 or 1 
          user:     whether to profile userspace: 0 or 1 
       -p/--separate=type,[types] 
           Separate profiles as follows : 
           none:     no profile separation 
           library:  separate shared library profiles per-application 
           kernel:   same as library, plus kernel profiles 
           thread:   per-thread/process profiles 
           cpu:      per CPU profiles 
           all:      all of the above 
       -c/--callgraph=#depth         enable callgraph sample collection with a maximum depth. 
                                     Use 0 to disable callgraph profiling. 
       --session-dir=dir             place sample database in dir instead of 
                                     default location (/var/lib/oprofile) 
       -i/--image=name[,names]       list of binaries to profile (default is "all") 
       --vmlinux=file                vmlinux kernel image 
       --no-vmlinux                  no kernel image (vmlinux) available 
       --kernel-range=start,end      kernel range vma address in hexadecimal 
       --buffer-size=num             kernel buffer size in sample units 
       --buffer-watershed            kernel buffer watershed in sample units (2.6 nly= 
       --cpu-buffer-size=num         per-cpu buffer size in units (2.6 only) 
       --note-table-size             kernel notes buffer size in notes units (2.4 only) 


       --xen                         Xen image (for Xen only) 
       --active-domains=<list>       List of domains in profiling session (for Xen only) 
                                     (list contains domain ids separated by commas) 






    2.使用方法 
    将我们之前编译好的oprofile和busybox装入模拟器 
    执行oprofile目录中的install.sh 将oprofile装入模拟器 
    adb push busybox /data/busybox 
    $adb shell  //进入模拟器shell 
    #chmod 777 /data/busybox 
    # /data/busybox --install /data/busybox 
    #export PATH=/data/busybox:$PATH:/data/oprofile 
    # mount -o remount rw / 
    # mount -o rw,remount -t yaffs2 /dev/mtdblock3 /system 
    # touch /etc/mtab 
    # echo nodev /dev/oprofile oprofilefs rw 0 0>/etc/mtab 
    # mkdir /dev/oprofile 
    # mount -t oprofilefs nodev /dev/oprofile    //这一句很重要,没有这一句会出现下面的错误 


    # opcontrol --init      
    cat: can't open '/dev/oprofile/cpu_type': No such file or directory 
    Unable to open cpu_type file for reading 
    Make sure you have done opcontrol --init 
    cpu_type 'unset' is not valid 
    you should upgrade oprofile or force the use of timer mode 


    # opcontrol --init     //初始化,只需运行一次 
    # opcontrol --setup --callgraph=2 --session-dir=/data/first --no-vmlinux 
    Using 2.6+ OProfile kernel interface. 
    Using log file /data/first/samples/oprofiled.log 
    Daemon started. 
    Profiler running. 
    # opcontrol --status 
    Daemon running: pid 637 
    Separate options: none 
    vmlinux file: none 
    Image filter: none 
    Call-graph depth: 2 
    # opcontrol --start     //启动profiler 
    Using 2.6+ OProfile kernel interface. 
    Using log file /var/lib/oprofile/samples/oprofiled.log 
    Daemon started. 
    Profiler running. 
    # /data/test/test     //运行我们的程序 ( 我的测试程序通过这条指令编译arm-none-linux-gnueabi-gcc -g -o test test.c -static -fno-omit-frame-pointer) 
    in c 

  • TAG: Android android 性能测试

     

    评分:0

    我来说两句

    Open Toolbar