zoukankan      html  css  js  c++  java
  • 使用OProfile来debug程序的性能

    OProfile的原理比较简单:现在的很多CPU都提供一个所谓性能计数器的东西(performance counter),大致的原理就是程序可以注册告诉CPU对什么event感兴趣(比如CPU_CYCLE,CPU经历了一次时钟周期),然后CPU在执行了相应的操作后,就会在性能计数器上加1,这样程序就可以取出。所以,使用OProfile来定位CPU使用率的问题,就变成了让oprofile收集程序运行过程中哪个可执行程序(或是so)中的哪个function,消耗的CPU CYCLE最多。

    OProfile不是每次有了event都会记录下来的,OProfile有一个sample(采样)的概念,其实就是定义经历了多少次event之后,记录下一个sample。所以,如果我们设置经历10000个CPU_CYCLE event之后记录一个sample,那么,最后在oprofile的输出中,一个sample就表示使用了10000个CPU CYCLE。

    下面就是如何使用oprofile了。OProfile需要一个内核module,这个module已经被集成进入了Linux 2.6.x内核;此外还有一个用户态的daemon程序,用来收集信息;再此外就是一些utilities了,用来控制oprofile和打印结果。

    所以在PC上调试就非常简单,现在大部分的Linux distribution的内核都打开了oprofile的这个module开关,所以只需要下载oprofile的源码,编译就OK了。但是在板子上就有一些麻烦了,如果板子上的内核编译时没有打开oprofile开关,那么就需要重新编译内核。

    ==================================== Separator ============================================

    在PC上,查看内核是否编译了oprofile可以通过这样:

    cat /boot/config-`uname -r` | grep OPROFILE

    应该有这样两行:

    CONFIG_HAVE_OPROFILE=y
    CONFIG_OPROFILE=m

    这表示打开了OPROFILE,而且oprofile被编译成了一个module。

    在板子上的话,就检查板子的kernel包中提供的config文件,看其中的OPROFILE部分,我的ZOOM板子上的信息是:

    CONFIG_HAVE_OPROFILE=y
    CONFIG_OPROFILE=y

    这表示打开了OPROFILE,但是没有编译成module,直接编译进内核了。

    ==================================== Separator ============================================

    OK,接下来就是在scratchbox中编译oprofile的源码,将prefix指到一个自定义的目录,然后将编译好的文件传到板子上。建议将所有东西都拷贝到/usr目录下即可。

    接下来就是:

    // 不监控linux kernel
    opcontrol --no-vmlinux
    // 如果要监控linux kernel,那要提供没有压缩过的,而且包含symbol信息的linux kernel文件,也就是vmlinux那个文件
    // uImage是去掉了symbol信息的内核文件,zImage是压缩过的内核文件(该文件的开头有一段解压代码,从而是自解压的文件)
    opcontrol --vmlinux=<your vmlinux file path>

    // 监控CPU_CYCLES event,每10000个event采样一次,内核和用户态的event都监控,生成最多10级的callgraph
    // --event中的0是unitmask,1表示监控内核态event,第二个1表示监控用户态event
    opcontrol --event=CPU_CYCLES:10000:0:1:1 --callgraph=10

    // 启动
    opcontrol --start

    // 启动要监控的应用程序
    ......

    // 关闭oprofile(这让oprofiled将所有收集到的数据都写入文件)
    // oprofile manual中建议使用opcontrol --dump来flush数据从而不用shutdown oprofiled,应该也是可以的
    opcontrol --shutdown

    // 查看总体summary数据
    opreport

    // 查看带symbol信息的数据(能看到哪个so/可执行程序的哪个函数使用了多少sample)
    opreport -l

    // 查看带callgraph的数据(最详尽的数据)
    opreport -l -c

    ==================================== Separator ============================================

    基本上就是这样了,更详细的信息去看oprofile的manual(网站上)。这里还有几点需要提一下:

    1. 板子上的是busybox,所以shell是ash,功能不是很全。这里opcontrol第一次运行的时候,就会报告有一行syntax error,大致是这样的一句代码:

    temp=${1/cell/CELL}

    我使用这样一句来代替的:

    temp=`echo $1|sed 's/cell/CELL/g'`

    2. opcontrol运行会报告oprofile内核module没有ready。但其实刚才已经看到了,oprofile已经在内核中了。这是由于opcontrol脚本的问题所导致的,这可以通过分析opcontrol脚本来解决。大致需要fix的几个地方是:

    a. opcontrol会检查/etc/mtab文件中是否有oprofilefs这一行,没有就认为oprofile在内核中没有。于是我手动在/etc/mtab中添加了一行:

    nodev /dev/oprofile oprofilefs rw

    b. oprofile会在/dev/oprofile目录下mount oprofilefs,他是通过检查/proc/filesystems文件中是否有oprofile这一行来判断mount是否做过了。由于我们修改了/etc/mtab,所以有时这里判断会出问题。如果发生了opcontrol报告说/dev/oprofile目录下某个文件找不到时,就是没有mount,手动帮他做一下就OK:

    mkdir /dev/oprofile
    mount -t oprofilefs nodev /dev/oprofile

    这些都可以通过阅读opcontrol这个脚本来解决。只要确定内核中有oprofile,就不用怀疑的去Fix就好了。

    3. opcontrol --start的时候,报告说wc -m执行出错,因为busybox中的wc不支持-m这个option,我用wc -c来代替。
  • 相关阅读:
    linux svn切换用户
    解决QQ“抱歉,无法发起临时会话,您可以 添加对方为好友以发送消息”
    node.js中http.respone.end方法概述
    niginx:duplicate MIME type "text/html" in nginx.conf 错误(转载)
    大三暑假实习,我们可以怎么做
    一个Java程序员的实习总结(2)
    正式工作的前奏——一个Java程序员的实习总结(1)
    【个人】当我秀智商的时候我秀什么
    基于java的设计模式入门(1)——为什么要学习设计模式
    【个人】我不愿让你一个人
  • 原文地址:https://www.cnblogs.com/super119/p/1924409.html
Copyright © 2011-2022 走看看