Android 使用Oprofile分析结果系统瓶颈 2010-12-29 17:33

弄了半天,Android Oprofile终于可以分析出结果了,下面把使用过程记录一下。

1. 首先CPU PMU必须支持Oprofile机制,S3C6410并不支持,幸好telechips tcc8900支持。

make menuconfig。做如下选择


编译内核,在目标板上运行。启动信息中会看到如下信息

<6>oprofile: using arm/armv6

说明内核已经添加了oprofile支持

好了,下面我们在Android2.1上执行oprofile。

2. adb shell或者在Android串口终端中运行opcontrol --quick命令,初始化oprofiled。

然后执行opcontrol --start

如果执行opcontrol --status 显示如下

# opcontrol --status

opcontrol --status

Driver directory: /dev/oprofile

Session directory: /data/oprofile

Counter 0:

name: CPU_CYCLES

count: 150000

Counter 1 disabled

Counter 2 disabled

oprofiled pid: 1028

profiler is running

650 samples received

0 samples lost overflow

说明oprofile正在收集数据。

执行你想分析的程序。我运行了一个2D 测试软件。执行完毕后,运行opcontrol --stop。停止分析

3. 使用adb pull等方式,将目标板的/data/oprofile 拉出来,会看到里面包含一个samples文件夹,还有abi、complete_dump、lock三个文件,有用的是samples文件,其他三个文件不知道有什么用。

4.拷贝samples文件夹到android源码的external/oprofile/result文件夹。result文件夹需要新建

5.需要执行opimprot_pull这个python脚本。由于脚本中使用了adb pull等方式,而我的linux环境上无法和目标板进行连接,最郁闷的是android自带的opimport等可执行文件无法从我的linux环境运行。因此改了一下脚本。

#!/usr/bin/python2.4 -E

import os

import re

import sys

def PrintUsage():

print "Usage:" + sys.argv[0] + " [-r] dir"

print " -r : reuse the directory if it already exists"

print " dir: directory on the host to store profile results"

if (len(sys.argv) > 3):

PrintUsage()

sys.exit(1)

# identify 32-bit vs 64-bit platform

stream = os.popen("uname -m")

arch_name = stream.readline().rstrip("\n");

stream.close()

# default path is prebuilt/linux-x86/oprofile

# for 64-bit OS, use prebuilt/linux-x86_64/oprofile instead

if arch_name == "x86_64":

arch_path = "/../../linux-x86_64/oprofile"

else:

arch_path = ""

try:

oprofile_event_dir = os.environ['OPROFILE_EVENTS_DIR']

except:

print "OPROFILE_EVENTS_DIR not set. Run \". envsetup.sh\" first"

sys.exit(1)

if sys.argv[1] == "-r" :

replace_dir = 1

output_dir = sys.argv[2]

else:

replace_dir = 0

output_dir = sys.argv[1]

if (os.path.exists(output_dir) and (replace_dir == 1)):

os.system("rm -fr " + output_dir)

try:

#os.makedirs(output_dir)

print "dont mkdir"

except:

if os.path.exists(output_dir):

print "Directory already exists:", output_dir

print "Try \"" + sys.argv[0] + " -r " + output_dir + "\""

else:

print "Cannot create", output_dir

sys.exit(1)

# get the samples off the phone

#result = os.system("adb pull /data/oprofile/samples " + output_dir + \

# "/raw_samples > /dev/null 2>&1")

result = 0

if result != 0:

print "adb pull failure, exiting"

sys.exit(1)

# enter the destination directory

os.chdir(output_dir)

stream = os.popen("find raw_samples -type f -name \*all")

# now all the sample files are on the host, we need to invoke opimport one at a

# time to convert the content from the ARM abi to x86 ABI

# break the full filename into:

# 1: leading dir: "raw_samples"

# 2: intermediate dirs: "/blah/blah/blah"

# 3: filename: e.g. "CPU_CYCLES.150000.0.all.all.all"

pattern = re.compile("(^raw_samples)(.*)/(.*)$")

for line in stream:

match = pattern.search(line)

leading_dir = match.group(1)

middle_part = match.group(2)

file_name = match.group(3)

dir = "samples" + middle_part

# if multiple events are collected the directory could have been setup

if not os.path.exists(dir):

os.makedirs(dir)

#cmd = oprofile_event_dir + arch_path + "/bin/opimport -a " + \

cmd = "opimport -a " + \

oprofile_event_dir + \

"/abi/arm_abi -o samples" + middle_part + "/" + file_name + " " + line

os.system(cmd)

stream.close()

# short summary of profiling results

#os.system(oprofile_event_dir + arch_path + "/bin/opreport --session-dir=.")

os.system("opreport --session-dir=.")


执行下面的命令,显示出如下结果:

$ ./opimport_pull result

dont mkdir

CPU: ARM V6 PMU, speed 0 MHz (estimated)

Counted CPU_CYCLES events (clock cycles counter) with a unit mask of 0x00 (No unit mask) count 150000

CPU_CYCLES:150000|

samples| %|

------------------

973277 51.9102 libskia.so

246957 13.1716 libdvm.so

242313 12.9239 no-vmlinux

230398 12.2884 libc.so

67471 3.5986 libcutils.so

25674 1.3693 libMali.so

20735 1.1059 libGLESv1_CM_mali.so

17357 0.9257 oprofiled

14659 0.7818 libandroid_runtime.so

9753 0.5202 libui.so

7462 0.3980 libutils.so

5828 0.3108 libsurfaceflinger.so

3904 0.2082 libm.so

3378 0.1802 libbinder.so

1779 0.0949 libEGL_mali.so

1539 0.0821 libstdc++.so

769 0.0410 gralloc.tcc92xx.so

591 0.0315 libGLESv1_CM.so

468 0.0250 libEGL.so

124 0.0066 libicuuc.so

87 0.0046 libopencorehw.so

81 0.0043 libGLES_android.so

80 0.0043 libz.so

69 0.0037 libpixelflinger.so

58 0.0031 libicui18n.so

43 0.0023 libsqlite.so

28 0.0015 liblog.so

22 0.0012 libnativehelper.so

6 3.2e-04 libandroid_servers.so

4 2.1e-04 linker

2 1.1e-04 init

2 1.1e-04 vold

2 1.1e-04 libhardware_legacy.so

2 1.1e-04 libtslib.so

1 5.3e-05 adbd

1 5.3e-05 inputraw.so

[wangmeng@android3 oprofile]$

更多相关文章

  1. Android(安卓)Build (1) -- Source Code Build Steps
  2. Ruby实现Android自动化屏幕适配
  3. 安装Android(安卓)2.2 SDK时出现的问题
  4. android创建文件夹和文件
  5. Activity的四种加载方式
  6. Android-webview和js脚本语言交互的时候怎么获取js方法的返回值
  7. 导入Eclipse工程到Android(安卓)studio
  8. 破解Xamarin
  9. Android(安卓)make脚本简记

随机推荐

  1. Android软件安全开发实践(上)
  2. [转]android开发新浪微博客户端 完整攻略
  3. Android Launcher开发(一)LiveFolder(实
  4. 国内几大Android应用市场试用小记——开
  5. android 解决wifi断线不稳定的问题-终极
  6. Android实现仿QQ登录可编辑下拉框
  7. Android广播机制——广播的注册
  8. 让 Android 应用提交更简单——用Worktil
  9. Android基于监听的事件处理机制
  10. 关于Android SDK工具Lint的误报:Class ref