为何使用 gprof
对 mips64 设备上某业务进行性能调优,由于 Linux 系统为深度定制系统且 mips CPU 的限制,valgrind / 内核 perf 工具都有法使用(尚未研究 OProfile)。strace 只能 trace system calls and signals
,因此考虑使用 gprof 进行性能调优。
gprof 使用注意事项
- 编译和链接都需要使用
-pg
选项。若链接时没使用该选项,会输出空数据 gmon.out。
1 | ~ # ls -al gmon.out |
查看 octeon mips64 app 生成的 gmon.out
- 嵌入式设备上没有 gprof 程序
- 把 gmon.out 传到 x86 PC
- 通过交叉编译工具链中的
mips64-octeon-linux-gnu-gprof
查看
1 | sunyongfeng@openswitch-OptiPlex-380:~/workshop/test$mips64-octeon-linux-gnu-gprof ./rtxx -Q |
如何在不退出的业务中使用 gprof
详见 Saving gmon.out before killing a process。
gprof 通过 atexit 注册函数 _mcleanup
,因此只要在退出前调用该函数即可。使用 SIGUSR1 信号,在信号处理函数中调用 _mcleanup
和 _exit
。可正常运行!代码如下。
1 |
|
SIGUSR1 十进制值是多少?
不同的 arch 对 signal 的值定义不一样。在 x86 中的定义一般为 10,但是在 octeon mips 中就不一样了,详见 arch/mips/include/asm/signal.h
:
1 |
所以,此时我只要 kill -16 my_proc
就会生成 gmon.out 了。
编译提示 Undefined reference to ‘dlsym’
链接参数加上 -ldl
即可。据说 C++ 的链接参数是 -Wl,--no-as-needed -ldl -pg
。
多线程使用 gprof
gprof 默认不支持多线程,通过 http://sam.zoy.org/writings/programming/gprof.html 提供的 gprof-helper 包装 pthread_create 函数,注入钩子后即可。
源代码如下。
- 通过
gcc -shared -fPIC gprof-helper.c -o gprof-helper.so -lpthread -ldl
编译该文件为共享库 - 通过
LD_PRELOAD=./gprof-helper.so your_program
应用该共享库
1 | /* gprof-helper.c -- preload library to profile pthread-enabled programs |