一.Oprofile简介
Profiling是对不同性能特征的数据的形式化总结或分析,它通常以图形和表的形式出现。它提供为特定的处理器事件收集的采样百分数或数量,比如cachemissrate、TLBmissrate等等。一般来说主要目的是为了找出软件中的性能瓶颈,然后有针对性的优化以提升软件的整体性能。
Oprofile是用于Linux的若干种评测和性能监控工具中的一种。它可以工作在不同的体系结构上,包括ARM,PowerPC,MIPS,IA32,IA64和AMDAthlon等等。它的开销很小,从Linux2.6版起,它被包含进了Linux内核中。
Oprofile可以收集有关处理器事件的信息,帮助用户识别诸如循环的展开、cache的使用率低、低效的类型转换和冗余操作、错误预测转移等问题。Oprofile是一种细粒度的工具,可以为指令集或者为函数、系统调用或中断处理例程收集采样。Oprofile通过取样来工作。使用收集到的评测数据,用户可以很容易地找出性能问题。
通过监察CPU的hardwareevents,oprofile可以在运行状态下对整个Linux系统进行profiling。Profiling的对象可以是Linuxkernel(包括modules和interrupthandlers),sharedlibraries或者应用程序。
从0.9.8版本开始,oprofile支持Perf_eventsprofilingmode模式。应用程序operf被用来控制profiling过程;而在legacymode下,是通过opcontrol脚本和oprofileddaemon来完成的。Operf不再象legacymode那样需要OProfilekerneldriver,它直接和LinuxKernelPerformanceEventsSubsystem打交道。使用operf,就可以用普通用户的身份来profiling用户的应用程序了,当然如果需要对整个系统来profiling的时候还是需要root权限的。
如果硬件不支持OProfile使用performancecounters,OProfile就只能工作在TimerMode下了。TimerMode只能在legacyprofilingmode下使用,即只能通过opcontrol脚本来控制。
Oprofile的优势:
Ÿ比较低的运行开销
Ÿ对被profiling的对象影响很小
Ÿ可以profiling中断服务程序(interrupthandlers)
Ÿ可以profiling应用程序和sharedlibraries
Ÿ可以profilingdynamicallycompiled(JIT)code
Ÿ可以对整个系统做profiling
Ÿ可以观察CPU内部的细节,例如cachemissrate
Ÿ可以多源代码做annotation
Ÿ可以支持instruction-level的profiling
Ÿ可以生成call-graphprofiles
不过OProfile也不是万能的,它也有自己的局限性:
Ÿ只能在x86,ARM,和PowerPC架构上生成callgraphprofiles
Ÿ不支持100%精确的instruction-levelprofiling
Ÿ对dynamicallycompiled(JIT)codeprofiling的支持还不完善。
无论如何,Oprofile的功能都比gprof要强很多,代价是配置起来会比较麻烦。
二.编译Oprofile
首先最好在Linuxkernel里面选中Oprofiledriver,以获得全面的支持。
因为笔者使用的是XilinxLinuxpre-built14.7,所以这里下载的是linux-xlnx-xilinx-v14.7.tar.gz
解压缩后,用以下命令调出Linuxkernel的配置界面:
exportARCH=arm
exportCROSS_COMPILE=arm-xilinx-linux-gnueabi-
makexilinx_zynq_defconfig
makexconfig或者makemenuconfig
在配置界面上将以下两项勾上:
Generalsetup--->
[*]Profilingsupport
OProfilesystemprofiling
然后makeuImage即可生成新的uImage,用来替换XilinxLinuxpre-built14.7中的Linuxkernelimage。同时我们也需要vmlinux来检查profiling的结果。
Oprofile需要popt,bfd,liberty库,要在嵌入式单板上使用这些库,需要手工完成交叉编译。
针对popt1.7,用以下命令完成编译:
./configure--prefix=/home/wave/xilinx/oprofileprj/rootfs--host=arm-xilinx-linux-gnueabi--with-kernel-support--disable-nls&&make&&makeinstall
针对binutils2.24,用以下命令完成编译:
./configure--host=arm-xilinx-linux-gnueabi--prefix=/home/wave/xilinx/oprofileprj/rootfs--enable-install-libbfd--enable-install-libiberty--enable-shared&&make&&makeinstall
不过--enable-install-libiberty没有效果,所以需要手工把libiberty.a和libiberty.h拷贝到相应的位置。
针对oprofile0.9.9,用以下命令完成编译:
./configure--host=arm-xilinx-linux-gnueabi--prefix=/home/wave/xilinx/oprofileprj/rootfs--with-kernel-support--with-binutils=/home/wave/xilinx/oprofileprj/rootfs&&make&&makeinstall
配置过程结束后可能会有以下提示,因为没有打算用GUI和profileJITedcode,所以直接忽视之。
config.status:executinglibtoolcommands
Warning:QTversion3wasrequestedbutnotfound.NoGUIwillbebuilt.
Warning:Theuseraccount'oprofile:oprofile'doesnotexistonthesystem.
ToprofileJITedcode,thisspecialuseraccountmustexist.
Pleaseaskyoursystemadministratortoaddthefollowinguserandgroup:
username:'oprofile'
groupname:'oprofile'
The'oprofile'groupmustbethedefaultgroupforthe'oprofile'user.
将编译完成的uImage,vmlinux,oprofilebinary,重新编译的没有-pg的libjpegbinary以及toolchain的libc打包放到SD卡中,准备在ZC706开发板上尝试profiledjpeg。
三.运行Oprofile
正常启动嵌入式Linux后,在开发板的console上一次输入以下命令:
mount/dev/mmcblk0p1/mnt
mkdir-p/home/root/work
cd/home/root/work
tarzxvf/mnt/jpeg-bin-nopg.tar.gz
cdjpeg-bin/bin
cp/mnt/park-2880x1800.jpg.
exportLD_LIBRARY_PATH=/home/root/work/jpeg-bin/lib
cd/home/root/work
tarzxvf/mnt/rootfs.tar.gz
cdrootfs
chownroot:root-R*
cp-Rbin/*/usr/bin
cp-Rlib/*/lib
cp/bin/which/usr/bin
cp/bin/dirname/usr/bin
mkdir-p/home/wave/xilinx/oprofileprj/rootfs/share
cp-R./rootfs/*/home/wave/xilinx/oprofileprj/rootfs
cd/home/root/work
tarzxvf/mnt/libc.tar.gz
cp./lib/libstdc*.*/lib
mkdir-p/home/wave/xilinx/libjpeg
cd/home/wave/xilinx/libjpeg
tarzxvf/mnt/jpeg-9.tar.gz
cp/mnt/vmlinux/home/root/work
cd/home/root/work/jpeg-bin/bin
opcontrol--init
opcontrol--vmlinux=/home/root/work/vmlinux
opcontrol--setup--event=CPU_CYCLES:100000::0:1--session-dir=/home/root/
operf--vmlinux/home/root/work/vmlinux./djpeg-bmppark-2880x1800.jpg>result.bmp
opreport-l./djpeg
完成这一步后,我们就可以看到profiling的结果了,在笔者的平台上看到的内容的主要部分如下:
root@zynq:~/work/jpeg-bin/bin#opreport-l./djpeg
Using/home/root/work/jpeg-bin/bin/oprofile_data/samples/forsamplesdirectory.
CPU:ARMCortex-A9,speed666667MHz(estimated)
CountedCPU_CYCLESevents(CPUcycle)withaunitmaskof0x00(Nounitmask)count100000
samples%imagenamesymbolname
1529358.6253libc-2.17.so/lib/libc-2.17.so
2044