弄了半天,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]$ |