关于xilinx zynq-7000带来的新的系统设计思路,以及profiling的对象libjpeg,前文已经描述过了,再此不再赘述。
一. oprofile简介
profiling是对不同性能特征的数据的形式化总结或分析,它通常以图形和表的形式出现。它提供为特定的处理器事件收集的采样百分数或数量,比如cache miss rate、tlb miss rate等等。一般来说,主要目的是为了找出软件中的性能瓶颈,然后有针对性的优化以提升软件的整体性能。
oprofile 是用于 linux 的若干种评测和性能监控工具中的一种。它可以工作在不同的体系结构上,包括arm, powerpc, mips, ia32, ia64 和 amd athlon等等。它的开销很小,从linux 2.6 版起,它被包含进了linux内核中。
oprofile可以收集有关处理器事件的信息,帮助用户识别诸如循环的展开、cache的使用率低、低效的类型转换和冗余操作、错误预测转移等问题。oprofile是一种细粒度的工具,可以为指令集或者为函数、系统调用或中断处理例程收集采样。oprofile 通过取样来工作。使用收集到的评测数据,用户可以很容易地找出性能问题。
通过监察cpu的hardware events,oprofile可以在运行状态下对整个linux系统进行profiling。profiling的对象可以是linux kernel (包括modules和interrupt handlers), shared libraries或者应用程序。
从0.9.8版本开始,oprofile支持perf_events profiling mode模式。应用程序operf被用来控制profiling过程;而在legacy mode下,是通过opcontrol脚本和oprofiled daemon来完成的。operf不再象legacy mode那样需要oprofile kernel driver,它直接和linux kernel performance events subsystem打交道。使用operf,就可以用普通用户的身份来profiling用户的应用程序了,当然如果需要对整个系统来profiling的时候还是需要root权限的。
如果硬件不支持oprofile使用performance counters,oprofile就只能工作在timer mode下了。timer mode只能在legacy profiling mode下使用,即只能通过opcontrol脚本来控制。
oprofile的website为:
可以支持的处理器的hardware event类型:
对于zynq-7000来说, 列出了arm cortex-a9内核pmu(performance monitor unit)所支持的所有hardware event种类,可以看出oprofile可以支持很多深入处理器内部的分析。
提供了一些oprofile生成的结果,可以方便开发者在开始使用之前了解oprofile能够做到哪些事情。
oprofile的详细使用文档:
oprofile的优势:
ÿ 比较低的运行开销
ÿ 对被profiling的对象影响很小
ÿ 可以profiling中断服务程序(interrupt handlers)
ÿ 可以profiling应用程序和shared libraries
ÿ 可以profiling dynamically compiled (jit) code
ÿ 可以对整个系统做profiling
ÿ 可以观察cpu内部的细节,例如cache miss rate
ÿ 可以多源代码做annotation
ÿ 可以支持instruction-level的profiling
ÿ 可以生成call-graph profiles
不过oprofile也不是万能的,它也有自己的局限性:
ÿ 只能在x86, arm, 和powerpc架构上生成call graph profiles
ÿ 不支持100%精确的instruction-level profiling
ÿ 对dynamically compiled (jit) code profiling的支持还不完善。
无论如何,oprofile的功能都比gprof要强很多,代价是配置起来会比较麻烦。
二. 编译oprofile
首先最好在linux kernel里面选中oprofile driver,以获得全面的支持。
下载linux kernel source:从 https://github.com/xilinx/linux-xlnx 可以下载到xilinx提供的验证好的内核。如果不方便使用linux下的git工具,可以单击页面上的releases找到相应的版本下载tar ball。下载的时候最好选tar.gz格式的,而不是zip格式的,因为后者在处理symbol link的时候有可能会出问题。
因为笔者使用的是xilinx linux pre-built 14.7,所以这里下载的是 linux-xlnx-xilinx-v14.7.tar.gz
解压缩后,用以下命令调出linux kernel的配置界面:
export arch=arm
export cross_compile=arm-xilinx-linux-gnueabi-
make xilinx_zynq_defconfig
make xconfig 或者make menuconfig
在配置界面上将以下两项勾上:
general setup --->
[*] profiling support
oprofile system profiling
然后make uimage即可生成新的uimage,用来替换xilinx linux pre-built 14.7中的linux kernel image。同时我们也需要vmlinux来检查profiling的结果。
oprofile需要popt, bfd, liberty库,要在嵌入式单板上使用这些库,需要手工完成交叉编译。
针对popt 1.7,用以下命令完成编译:
./configure --prefix=/home/wave/xilinx/oprofileprj/rootfs --host=arm-xilinx-linux-gnueabi --with-kernel-support --disable-nls && make && make install
针对binutils 2.24,用以下命令完成编译:
./configure --host=arm-xilinx-linux-gnueabi --prefix=/home/wave/xilinx/oprofileprj/rootfs --enable-install-libbfd --enable-install-libiberty --enable-shared && make && make install
不过--enable-install-libiberty没有效果,所以需要手工把libiberty.a和libiberty.h拷贝到相应的位置。
针对oprofile 0.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 && make install
配置过程结束后可能会有以下提示,因为没有打算用gui和profile jited code,所以直接忽视之。
config.status: executing libtool commands
warning: qt version 3 was requested but not found. no gui will be built.
warning: the user account 'oprofile:oprofile' does not exist on the system.
to profile jited code, this special user account must exist.
please ask your system administrator to add the following user and group:
user name : 'oprofile'
group name: 'oprofile'
the 'oprofile' group must be the default group for the 'oprofile' user.
将编译完成的uimage,vmlinux,oprofile binary,重新编译的没有-pg的libjpeg binary以及tool chain的libc打包放到sd卡中,准备在zc706开发板上尝试profile djpeg。
三. 运行oprofile
正常启动嵌入式linux后,在开发板的console上一次输入以下命令:
mount /dev/mmcblk0p1 /mnt
mkdir -p /home/root/work
cd /home/root/work
tar zxvf /mnt/jpeg-bin-nopg.tar.gz
cd jpeg-bin/bin
cp /mnt/park-2880x1800.jpg .
export ld_library_path=/home/root/work/jpeg-bin/lib
cd /home/root/work
tar zxvf /mnt/rootfs.tar.gz
cd rootfs
chown root:root -r *
cp -r bin/* /usr/bin
cp -r lib/* /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
tar zxvf /mnt/libc.tar.gz
cp ./lib/libstdc*.* /lib
mkdir -p /home/wave/xilinx/libjpeg
cd /home/wave/xilinx/libjpeg
tar zxvf /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 -bmp park-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/ for samples directory.
cpu: arm cortex-a9, speed 666667 mhz (estimated)
counted cpu_cycles events (cpu cycle) with a unit mask of 0x00 (no unit mask) count 100000
samples % image name symbol name
15293 58.6253 libc-2.17.so /lib/libc-2.17.so
2044 7.8356 libjpeg.so.9.0.0 ycc_rgb_convert
1964 7.5289 libjpeg.so.9.0.0 jpeg_idct_16x16
1918 7.3526 libjpeg.so.9.0.0 decode_mcu
1570 6.0186 libjpeg.so.9.0.0 jpeg_idct_islow
1567 6.0071 djpeg finish_output_bmp
528 2.0241 libjpeg.so.9.0.0 jpeg_fill_bit_buffer
397 1.5219 djpeg put_pixel_rows
73 0.2798 vmlinux __copy_from_user
70 0.2683 libjpeg.so.9.0.0 decompress_onepass
65 0.2492 libjpeg.so.9.0.0 jpeg_huff_decode
56 0.2147 vmlinux get_page_from_freelist
50 0.1917 vmlinux __memzero
45 0.1725 vmlinux __copy_to_user_std
41 0.1572 vmlinux _raw_spin_unlock_irqrestore
15 0.0575 vmlinux do_page_fault
14 0.0537 vmlinux __generic_file_aio_write
13 0.0498 vmlinux _raw_spin_unlock_irq
11 0.0422 vmlinux free_hot_cold_page
11 0.0422 vmlinux vector_swi
10 0.0383 vmlinux handle_pte_fault
从结果中我们可以看到libjpeg.so.9.0.0, djpeg和vmlinux中的symbol name已经可以被正确的解析出来了,和gprof的结果基本一致。相比gprof,oprofile可以在更大的范围内完成profiling。
我们还可以用以下命令观察源代码中特定行的执行时间,进一步缩小优化的范围,达到事半功倍的效果。
opannotate --source ./djpeg > opannotate.txt
四. 小结
通过实验,我们可以看到oprofile可以提供更丰富的profiling结果,可以更好的帮助开发者找到瓶颈,通过有针对性的优化提升软件性能;profiling的结果也可以帮助开发者将性能瓶颈代码通过xilinx hls工具用硬件加速器来实现,从而为进一步提升整个嵌入式系统的性能打开了大门。
5G竞争,网络建设先行!中国移动决心在5G时代争先
S3C2440的中断寄存器的分类及中断的过程分析
可调电源幅值、频率的陀螺电机
逆变器OEM/ODM生产厂家哪家好
无线对讲机日常使用中的常见问题及正确的操作方法经验分享(下)
使用oprofile对软件做profiling
SDCardUtils封装类应用:设备信息获取实现方法
带你快速了解国内首个加密级数字资产交易平台正式上线!
直流电子负载带载短路,无输出怎么办?
中国移动提出了5G+计划在5G+4G方面需在三方面进行协同发展
OpenDaylight中的Karaf
架空地线的作用是什么
2021行家说显示年:合易科技带你遇见技术未来
电子芯闻早报:亿航Ghost 2.0,大疆Phantom X
板级埋人式封装工艺流程与技术
关于AR你需要了解的10个关键数据
“刚柔并济”或将成为未来机器人市场主要方向
排电阻(集成电阻)引线的识别
芯片缺货危机爆发背后的三个根源性问题
贸泽电子备货最新控制集成式电源系统 可控制两相或三相交流电机