Android 使用Oprofile分析结果系统瓶颈

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

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

 

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

make menuconfig。做如下选择

Android 使用Oprofile分析结果系统瓶颈_第1张图片
Android 使用Oprofile分析结果系统瓶颈_第2张图片

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

<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]$ 

你可能感兴趣的:(android,Path,profiling,events,output,linker)