正文  高级教程 > 程序优化 >

Oprofile在Android中的应用 android开发教程

1 oprofile 相关介绍Oprofile 是用于 Linux 的若干种评测和性能监控工具中的一种。它可以工作在不同的体系结构上,包括 IA32 、 IA64 和 AMD Athlon 系列。它的开销小,将被包含在( Linux ) 2.......

1 oprofile 相关介绍

Oprofile 是用于 Linux 的若干种评测和性能监控工具中的一种。它可以工作在不同的体系结构上,包括 IA32 、 IA64 和 AMD Athlon 系列。它的开销小,将被包含在( Linux ) 2.6 版的内核中。

Oprofile 可以帮助用户识别诸如循环的展开、高速缓存的使用率低、低效的类型转换和冗余操作、错误预测转移等问题。它收集有关处理器事件的信息,其中包括 TLB 的故障、停机、存储器访问、位于 DCU (数据高速缓存单元)中的总线路数、一个 DCU 故障的周期数 , 以及不可高速缓存的和可高速缓存的指令的获取数量。 Oprofile 是一种细粒度的工具,可以为指令集或者为函数、系统调用或中断处理例程收集采样。 Oprofile 通过取样来工作。使用收集到的评测数据,用户可以很容易地找出性能问题。

Oprofile 工具概述:

       op_help: 列出可用的事件,并带有简短的描述

       opcontrol: 控制 Oprofile 的数据收集

       oprofpp: 检索有用的评测数据

       op_time: 为系统上的所有映像列出相关的评测值

       op_to_source: 产生带注解的源文件、汇编文件或源文件和汇编文件的混合

op_merge: 合并属于同一个应用程序的采样文件

op_import: 将采样数据库文件从外部格式( abi )转换为本地格式

opreport: 显示分析结果


2 oprofile 的移植


2.1 相关资源

源码包 :

     Oprofile-0.9.4.tar.gz

     gettext-0.18.1.1.tar.bz2

     buildroot-2010.02.tar.bz2

     Popt-1.7.tar.gz

     Binutils-2.19.51.0.3.tar.bz2

     busybox-1.8.1.tar.bz2

     linux-2.6.29-Android-1.0_r1.tar.gz

编译工具:

       arm-2008q3-72-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2

 

       2.2 详细步骤 :


       1. 在交叉编译之前需要做的一些工作 :

( 1 ) 打开内核的 Oprofile 选项

            通过 make menuconfig=>general setup=>

            [*] Profiling support (EXPERIMENTAL)

            [ ]Activate markers

            [*] OProfile system profiling (EXPERIMENTAL)

( 2 )选择安装交叉编译链

              修改 ~/.bashrc 添加 arm-none-linux-gnueabi 的路径。

PATH=$PATH: /home/cuiyan/work/arm-2008q3/bin/

( 3 )配置编译、链接参数

$:export CC=arm-none-linux-gnueabi-gcc

        $:export CXX=arm-none-linux-gnueabi-g++

$:export CFLAGS=-static

$:export CXXFLAGS=-static

$:export CPPFLAGS=-staitc


2 交叉编译 popt 库

           $:cd /home/cuiyan/work/oprofile/popt/

           $:tar xfz gettext-0.18.1.1.tar.bz2

           $:cd gettext-0.18.1.1

           $:./configure –prefix=/usr

           $:make

           $:make install

           $:cd ../


$:tar xfz popt-1.7.tar.gz

  $:cd popt-1.7

  $:./configure --with-kernel-support --host=arm-none-linux-gnueabi

--prefix=/home/cuiyan/work/oprofile/popt/poptinstall/

  $:make

  $:make install

  $: cp /home/cuiyan/work/oprofile/popt/poptinstall/lib/* /home/cuiyan/work/arm-2008q3/arm-none-linux-gnueabi/lib

  $: cp /home/cuiyan/work/oprofile/popt/poptinstall/include/* /home/cuiyan/work/arm-2008q3/arm-none-linux-gnueabi/include


3 静态交叉编译 binutils

        $:cd /home/cuiyan/work/oprofile/binutils/

        $:sudo apt-get install makeinfo


$:tar jxf binutils-2.19.51.0.3.tar.bz2

$:cd binutils-2.19.51.0.3

$:./configure --with-kernel-support --host= arm-none-linux-gnueabi

--prefix=/home/cuiyan/work/oprofile/binutils/binutils-install/

$:make

$:make install

$:c p /home/cuiyan/work/oprofile/binutils/binutils-install/lib/* /home/cuiyan/work/arm-2008q3/arm-none-linux-gnueabi/lib

$:c p /home/cuiyan/work/oprofile/binutils/binutils-install/include/* /home/cuiyan/work/arm-2008q3/arm-none-linux-gnueabi/include


4 静态交叉编译 oprofile

      $:cd /home/cuiyan/work/oprofile/oprofile/

$: tar zxf oprofile-0.9.4.tar.gz

$:cd oprofile-0.9.4

$:/configure --with-linux=/home/cuiyan/mid/gongban/ --with-kernel-support

--host= arm-none-linux-gnueabi

--prefix=/home/cuiyan/work/oprofile/oprofile/oprofile-install

$:make

$:make install

通过 1-4 操作,可在 oprofile-install/bin 目录下查看到一些 oprofile 的工具。

$:bin$ file ophelp

ophelp: ELF 32-bit LSB executable, ARM, version 1 (SYSV),  dynamically linked  (uses shared libs), for GNU/Linux 2.6.14, not stripped 。

 

5 转换动态链接为静态链接

虽然在之前指定了 static 参数,但是编译出来的结果仍然是动态链接的。这个是因为 Oprofile 在链接库时运用到了 libtool 工具。对于如何通过对 libtool 文件的修改使其直接产生静态链接的文件,目前未进行研究,而是直接手动编译成静态。

具体方法如下:

就 ophelp 命令来讲:

$:oprofile-0.9.4$ cd utils/

$:utils$ ls

Makefile Makefile.am Makefile.in opcontrol ophelp ophelp.c ophelp.o

$:utils$ rm ophelp

$:utils$ cd ..

$:oprofile-0.9.4

$ make

注:由于 ophelp 被删除,则它要重新生产,在 make 过程中可以查看相关生成指令。

arm-none-linux-gnueabi-gcc -W -Wall -fno-common -Wdeclaration-after-statement -o ophelp ophelp.o ../libop/libop.a ../libutil/libutil.a /work/pop t/popinstall/lib/ libpopt.so -liberty -ldl -Wl,--rpath -Wl,/work/popt/popinstall/lib -Wl,--rpath -Wl,/work/popt/popinstall/lib

 

$:oprofile-0.9.4$ cd utils/

$:utils$ rm ophelp

$:utils$ arm-none-linux-gnueabi-gcc -W -Wall -fno-common -Wdeclaration-after-statement -o ophelp ophelp.o ../libop/libop.a ../libutil/libutil.a /work/popt/popinstall/lib/ libpopt.a -liberty -ldl -Wl,--rpath -Wl,/work/popt/popinstall/lib -Wl,--rpath -Wl,/work/popt/popinstall/lib – static

$:utils$ file ophelp

ophelp: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked , for GNU/Linux 2.6.14, not stripped

则 ophelp 为静态链接,不依赖库,可以直接在开发板上运行。其他 Oprofile 指令相应通过手动编译生成。除其中 opcontrol 为 shell 脚本,是源码包自带的。

6 移植 busybox

由于要运用 oprofile 工具,必须先运用 opcontrol 进行初始化工作。而 opcontrol 是个 shell 脚本。首先修改 opcontrol 文件。

#!/bin/sh 改为 #!/system/bin/sh

把 oprofile 工具放在实验板的 /sbin 目录下。

Export PATH=$PATH:/sbin

$:./opcontrol –init

出现错误 :

test: not found

id: not found

test: not found

grep: not found

test: not found

grep: not found

test: not found

test: not found

test: not found

…………

这是由于 Android 提供的命令过于精简,因此需要移植 busybox ,来运行 opcontrol 。

通过下载 busybox 最新版本,进行交叉编译。我的实验板已有 busybox 工具,所以没有再次移植。以下简要介绍 busybox 的移植步骤(仅供参考):

( 1 )在主机上交叉编译 busybox ,要在 make menuconfig 中选择静态链接

( 2 )把 busybox 复制到实验板的 /data/busybox/ 下。

# :cd /data/busybox

# :chmod +x busybox

# :export PATH=$PATH:/data/busybox/

# :./busybox -install


修改 opcontrol 文件:

BINDIR =”/data/busybox”

PATH 中加入 /data/busybox

 

7 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

解决方法:

#rm /etc/mtab

#touch /etc/mtab

#vi /etc/mtab

编辑以下内容:

nodev /dev/oprofile oprofilefs rw 0 0

重新执行:

#opcontrol --init

到此, oprofile 移植成功。


有时在 mtab 文件已经存在的情况下还会出现以下错误:

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

解决方法:
Step1 :重新启动 target
step2 :执行 # ./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
Step3:  删除 /etc 目录下的 mtab 文件
          r m -f /etc/mtab
Step4: 执行 # ./opcontrol --init
       显示:
       # ./opcontrol --init
       grep: /etc/mtab: No such file or directory
       grep: /etc/mtab: No such file or directory
Step5: 重新在 /etc/ 目录下创建 mtab 并添加“ nodev /dev/oprofile oprofilefs rw 0 0”
         touch /etc/mtab
         Vi /etc/mtab
         Insert  "nodev /dev/oprofile oprofilefs rw 0 0"   ---> 在 mtab 中添加的内容
Step6: 执行 # ./opcontrol --init
         ok

 

3 oprofile 的相关应用


(1) 相关命令

#opcontrol --init

---> During initialization phase, the command can load oprofile.ko module in to kernel, and mount oprfilefs. After that, some files and directories are exported in to /dev/oprofile, such as: cpu_type, dump, enable, pointer_size, stats as so on.

 

# opcontrol --setup --no-vmlinux

---> Configure OProfile not to inspect kernel, if necessary, assign kernel with command : ./opcontrol –setup–vmlinux= /path/to/kernel

 

# opcontrol --start

---> Start up OProfile daemon routine oprofiled, which writes sampled data to /var/lib/oprofile/samples/, the log file is located at /var/lib/oprofile/oprfiled.log

 

# opcontrol --dump

---> The purpose of this command is to read all the sampled data to /var/lib/oprofile/samples/ before the analysis of performance.

 

# opcontrol --stop

---> The purpose of this command is to stop data coollection

 

#opcontrol –shutdown

---> The purpose of this command is to stop data coollection and kill daemon

 

#opcontrol –reset

---> The purpose of this command is to clear out data from current session

 

#opcontrol –deinit

---> The purpose of this command is to unload the oprofile module and oprofilefs


(2) 详细应用步骤

a ) 没有指定内核下的性能监测:

# opcontrol --init

# opcontrol --setup --no-vmlinux

# opcontrol –start

# opcontrol --dump

# opreport

 

b) 指定内核的情况下性能监测:
将编译内核时生成的 vmlinux文件复制到 sdcard/kernel/目录下。

# opcontrol --init

# opcontrol --setup --vmlinux=/sdcard/kernel/vmlinux

objdump: not found

objdump: not found

The specified file /sdcard/kernel/vmlinux does not seem to be valid

Make sure you are using the non-compressed image file (e.g. vmlinux not vmlinuz)

分析:

参看 oprocontrol 源码,由于在指定内核镜像时,会用到 objdump 应用程序检测镜像中的 .text 段内容 , 而在开发板上面没有交叉编译的 objdump 应用程序,所以不能通过判断,以至于,即使指定的是未压缩的内核镜像,也被误认为压缩的了。

解决方法:

通过采用编译静态链接 ophelp 的具体方法,编译生成静态链接的 objdump ,然后将 binutils-2.19.51.0.3/binutils 下的 objdump 拷贝到开发板的 /sbin 目录下

重新执行:

# opcontrol --setup --vmlinux=/vmlinux

#opcontrol -start

#opcontrol –dump

#opreport