内容概要
1.oprofile介绍
2.oprofile安装及Linux内核编译
3.oprofile使用
一、oprofile 介绍
oprofile 是 Linux 平台上,类似 INTEL VTune 的一个功能强大的性能分析工具。 其支持两种采样(sampling)方式:基于事件的采样(event based)和基于时间的采样(time based)。
基 于事件的采样是oprofile只记录特定事件(比如L2 cache miss)的发生次数,当达到用户设定的定值时oprofile 就记录一下(采一个样)。这种方式需要CPU 内部有性能计数器(performace counter)。现代CPU内部一般都有性能计数器;
基于时间的采样是oprofile 借助OS 时钟中断的机制,每个时钟中断 oprofile 都会记录一次(采一次样)。引入的目的在于,提供对没有性能计数器 CPU 的支持。其精度相对于基于事件的采样要低。因为要借助 Os时钟中断的支持,对禁用中断的代码oprofile不能对其进行分析。
oprofile 在Linux 上分两部分,一个是内核模块(oprofile.ko),一个为用户空间的守护进程(oprofiled)。前者负责访问性能计数器或者注册基于时间采样 的函数(使用register_timer_hook注册之,使时钟中断处理程序最后执行profile_tick 时可以访问之),并采样置于内核的缓冲区内。后者在后台运行,负责从内核空间收集数据,写入文件。
二、oprofile安装及Linux内核编译
I. Oprofile安装
Oprofile 包含在 Linux 2.6版本的内核中, 是用于 Linux 的若干种评测和性能监控工具中的一种。
也可从官方网站下载源码进行编译安装;具体安装步骤:
1. ./configure --with-kernel-support
注:在编译过程中,这一步出现的问题是:(1)缺少libiberty.h头文件;(2)缺少popt;
libiberty.h头文件在binutils-devel package中,需要下载这个包进行安装;也可通过新立德
进行安装。可以用sudo apt-get install binutil-dev 进行包安装。
Popt存在libpopt-devel package中,同样需要进行下载安装;
sudo apt-get install libpopt-dev;
2. make
3. make install
oprofile 安装完成后会生成以下工具集:
/usr/bin/oprofiled 守护进程
/usr/bin/opcontrol 控制前端,负责控制与用户交互,用得最多
/usr/bin/opannotate 根据搜集到的数据,在源码或者汇编层面上注释并呈现给用户
/usr/bin/opreport 生成二进制镜像或符号的概览
/usr/bin/ophelp 列出oprofile支持的事件
/usr/bin/opgprof 生成gprof格式的剖析数据
opstack: 产生调用图profile,但要求x86/2.6的平台,并且linux2.6安装了call-graph patch
oparchive: 将所有的原始数据文件收集打包,可以到另一台机器上进行分析。
op_import: 将采样的数据库文件从另一种abi转化成本地格式。
运行oprofile需要root权限,因为它要加载profile模块,启动oprofiled后台程序等。所以在运行之前,就需要切换到root。
II. Linux 内核编译
由于oprofile 是可对内核进行评测和性能监控的工具,所以需要有内核支持。但是在ubuntu
下面并没有内核源码,所以需要下载本机对应版本的内核源码,进行编译安装;
编译新内核的步骤如下:
(1)将下载的内核放在/usr/src 目录下;进行解压:tar -jxvf linux-source-2.6.27.tar.bz2;
(2)接下来对内核进行配置:make menuconfig(or make xconfig),我选择使用此命令;
在进行配置过程中,General Setup中的Local version - append to kernel release是可以自己
定制自己喜欢的内核名字; Load an Alternate Configuration File 此选项可以引用系统中的
配置文件; Save an Alternate Configuration File 是将重新配置的.config文件进行保存。
在配置之前,可以用以下命令进行清除。
Make clean :可以把以前编译的文件进行清除;
Make mrproper :可以清除以前的配置文件;建议新手不用;最好对以前的.config文件进行配置。
.config文件是内核源码中自带的./usr/src/linux-source-2.6.27/arch/x86/configs下
面的config文件 再根据menuconfig中的选项进行裁减后获得的最终的config文件。
(3) make 进行内核编译
编译完成后会在/boot目录下生成几个重要的文件;vmlinuz-2.6.27、System.map 等;
其中config文件生成在/linux-source-2.6.27目录下,需要拷贝到/boot目录下面。
(4)make modules_install 安装配置中选定的模块。
(5)make install
(6)检查是否生成initrd镜像文件,在ubuntu下并没有生成,需要在/boot下面使用命令:
mkinitramfs -o initrd.img.2.6.27.18 生成镜像文件。
(7)在/boot/grub下面编辑 menu.lst 文件,按照格式将新内核信息进行添加;只有在此处对新内核
添加,系统启动后才会被引导进入新内核。
如果配置符合系统要求,按照这个顺序就可以编译一个新内核了。
三、oprofile使用
oprofile要在root权限下使用:
a. 初始化
opcontrol --init
该命令会加载oprofile.ko模块,mount oprofilefs成功后会在/dev/oprofile/目录下导出一
些文件和目录如: cpu_type, dump, enable, pointer_size, stats.
b. 配置
1. 首先,配置 OProfile 是否应该监视内核。这是在启动 OProfile 前需要的配置选项。
以及对计数事件和样本计数的设置,计数的CPU模式(用户态、核心态)是系统默认项;
如果oprofile监视评测内核自身:
opcontrol –vmlinux=/src/urc/linux-source-2.6.27/vmlinux
如果oprofile不用监视评测内核:
opcontrol --no-vmlinux.
在此体系结构Family10h中默认的配置为:
opcontrol –event=CPU_CLK_UNHALTED:100000
如果配置守护进程写入文件的方式,用以下命令:
opcontrol --separate=<choice>
<choice> 可以是以下之一:
none — 不要分离档案(默认)
library — 为库生成每个应用程序的档案
kernel — 为内核和内核模块生成每个应用程序的档案
all — 为库生成每个应用程序的档案,为内核和内核模块生成每个应用程序的档案
注意问题:
(1)oprofile可以在此进行事件设置;
通过opcontrol --list-events命令可以查看此结构中支持的事件;
通过opcontrol --event=L2_CACHE_MISS:500 --event=L1_DTLB_MISS_AND_L2_DTLB_HIT:500
--event=.........命令来进行事件的设置;
此命令--event参数必须依次给出,无论有多少个,不可分行,切记!
通过opcontrol –status命令可以查看自己已经配置的事件;
(2)对于每一次测试过程中,如果需要进行事件的重新设置,就必须重启daemon,它是
一个守护进程。也就是说,收集数据完成后,要用--shutdown命令来停止daemon,而不是
--stop(此命令只是停止profiling),这样再次进行—start命令就可以使用新的事件设置;
(3)一次评测结束后,旧的profiling data 还是存在的,用—reset或者—save命令来清理或者
保存数据;
c. 启动
opcontrol --start
d. 运行待分析之程序
gcc -o wls wls.c; 生成 wls.o文件; ./wls
e. 取出数据
opcontrol –dump
数据被写进 /var/lib/oprofile/samples /oprofiled.log
f. 停止评测
opcontrol --stop
g. 使用opreport分析结果
opreport -l ./wls
根据设置的事件进行评测,将评测的结果一一显示出来。
h. 使用opannotate分析结果
如果对源码进行分析,可以通过opannotate工具实现
编译 : gcc -g wls.c -o wls
分析 : opannotate --source ./wls
总结一下:
1. opcontrol –init 加载模块,mout /dev/oprofile 创建必需的文件和目录
2. opcontrol --no-vmlinux 或者 opcontrol --vmlinux=/boot/vmlinux-`uname -r` 决定是否对kernel进行profiling
3. opcontrol --reset 清楚当前会话中的数据
4. opcontrol --start 开始profiling
5. ./wls 运行应用程序,oprofile会对它进行profiling
6. opcontrol --dump 把收集到的数据写入文件
7. opcontrol --stop 停止profiling
8. opcotrol -h 关闭守护进程oprofiled
9. opcontrol --shutdown 停止oprofiled
10. opcontrol --deinit 卸载模块
常用的是3→7这几个过程,得到性能数据之后,可以使用opreport, opstack, opgprof, opannotate
几个工具进行分析,我常用的是opreport, opannotate进行分析。
四、 实例演示
下面以AMR的解码源码为例,来分析代码的性能。
首先,要对即将分析的代码进行编译:
(1)编译源代码的库文件:
在目录 /home/wls/应用软件/AMREngineC_OKI_source/AMRDecEngine下执行 make 命令;
生成文件:libAMRDecEngine.a 此文件为归档库文件。
(2)编译源代码的主文件:
在目录 /home/wls/应用软件/AMREngineC_OKI_source/TestAMRDec/Win32下执行 make 命令;
生成文件:TestAMR 此文件为可执行文件。
将TestAMR 复制到上层目录:cp TestAMR ..
执行命令:./TestAMR AMRDec.par 生成 TestAMRDec.wav
其次,执行oprofile的命令并进行相应设置:
root@wls-desktop:~/TestAMRDec# opcontrol --init
root@wls-desktop:~/TestAMRDec# opcontrol --no-vmlinux
root@wls-desktop:~/TestAMRDec# opcontrol --event= CPU_CLK_UNHALTED:5000
--event=DATA_CACHE_MISSES:1000 --event=INSTRUCTION_CACHE_MISSES:1000
--event=MEMORY_REQUESTS:1000
root@wls-desktop:~/TestAMRDec# opcontrol --status
Daemon running: pid 14979
Event 0: CPU_CLK_UNHALTED:5000:0:1:1
Event 1: DATA_CACHE_MISSES:1000:0:1:1
Event 2: INSTRUCTION_CACHE_MISSES:1000:0:1:1
Event 3: MEMORY_REQUESTS:1000:131:1:1
Separate options: none
vmlinux file: none
Image filter: none
Call-graph depth: 0
root@wls-desktop:~/TestAMRDec# opcontrol –start
Using 2.6+ OProfile kernel interface.
Reading module info.
Using log file /var/lib/oprofile/samples/oprofiled.log
Daemon started.
Profiler running.
root@wls-desktop:~/TestAMRDec# ./TestAMR AMRDec.par
===================================================
Audio Length [msec] : 10020
Audio Frames [frame] : 501
Audio Packets [packet] : 501
Decoded Bytes [byte] : 7014
Average Bitrate [kbps] : 5.600
Decoding Time [msec] : 40 (250.500 Times)
===================================================
root@wls-desktop:~/TestAMRDec# opcontrol --dump
root@wls-desktop:~/TestAMRDec# opcontrol --stop
Stopping profiling.
root@wls-desktop:~/TestAMRDec# opreport -l ./TestAMR
数据分析结果如下: