1.ldd 用来显示进程所依赖的动态库路径
[root@iZ94xjteonrZ C++]# ldd test
linux-vdso.so.1 => (0x00007fff8cb08000)
libprofiler.so.0 => /usr/local/lib/libprofiler.so.0 (0x00007fb1f0d6a000)
libunwind.so.8 => not found
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb1f0b4c000)
libc.so.6 => /lib64/libc.so.6 (0x00007fb1f07b9000)
libunwind.so.7 => not found
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fb1f04b2000)
libm.so.6 => /lib64/libm.so.6 (0x00007fb1f022e000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb1f0018000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb1f0f83000)
[root@iZ94xjteonrZ C++]#
export LD_LIBRARY_PATH 的使用 用来设置环境变量 设置共享库的搜索位置
2.
1. 下载libunwind (wget http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz)
mkdir ../libunwind
./configure prefix=/home/tools/libunwind
make && make install
2. 下载 gperftools (wget http://code.google.com/p/gperftools/downloads/list/gperftools-2.0.tar.gz)
mkdir ../gperftools
./configure prefix=/home/tools/gperftools --enable-frame-pointers
make && make install
3. export LD_LIBRARY_PATH=/home/tools/gperftools/lib
export PATH=$PATH:/home/tools/gperftools/bin
4. mkdir ../test && cd ../test
vi test.cpp
#include <google/profiler.h>
#include <iostream>
using namespace std;
void test1()
{
int i = 0;
while (i < 1000)
{
i++;
}
}
void test2()
{
int i = 0;
while (i < 2000)
{
i++;
}
}
void test3()
{
for (int i = 0; i < 100000; ++i)
{
test1();
test2();
}
}
int main()
{
ProfilerStart("test.prof"); // test.prof is the name of profile file
test3();
printf("Finish!");
ProfilerStop();
return 0;
}
5. 编译
g++ -o test test.cpp -I /home/tools/gperftools/include -I /home/tools/libunwind/include -L/home/tools/gperftools/lib/ -lprofiler -L/home/tools/libunwind/lib/ -lunwind
6. ./test
生成test.prof文件
7. pprof --text test test.prof
输出:
Using local file test.
Using local file test.prof.
Total: 100 samples
59 59.0% 59.0% 59 59.0% test2
40 40.0% 99.0% 40 40.0% test1
1 1.0% 100.0% 1 1.0% test3
官方文档:http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
分析输出
pprof脚本用于分析profile文件并输出结果,包括文本和图形两种输出风格。
例如:demo是目标程序,my.prof是profile文件
生成文本风格结果:pprof --text ./demo my.prof > profile.txt
生成图形风格结果:pprof --pdf ./demo my.prof > profile.pdf
对于一个函数的CPU使用时间分析,分为两个部分:
1.整个函数消耗的CPU时间,包括函数内部其他函数调用所消耗的CPU时间
2.不包含内部其他函数调用所消耗的CPU时间(内联函数除外)
关于文本风格输出结果
序号 | 说明 |
1 | 分析样本数量(不包含其他函数调用) |
2 | 分析样本百分比(不包含其他函数调用) |
3 | 目前为止的分析样本百分比(不包含其他函数调用) |
4 | 分析样本数量(包含其他函数调用) |
5 | 分析样本百分比(包含其他函数调用) |
6 | 函数名 |
关于图形风格输出结果
1.节点
每个节点代表一个函数,节点数据格式:
Class Name Method Name local (percentage) of cumulative (percentage) |
local时间是函数直接执行的指令所消耗的CPU时间(包括内联函数);性能分析通过抽样方法完成,默认是1秒100个样本,一个样本是10毫秒,即时间单位是10毫秒;
cumulative时间是local时间与其他函数调用的总和;
如果cumulative时间与local时间相同,则不打印cumulative时间项。
2.有向边
调用者指向被调用者,有向边上的时间表示被调用者所消耗的CPU时间
示例
代码如下,可以看出,CPU消耗集中在func1()和func2()两个函数,func2()消耗时间约为func1()的两倍。
#include <google/profiler.h> #include <iostream> using namespace std; void func1() { int i = 0; while (i < 100000) { ++i; } } void func2() { int i = 0; while (i < 200000) { ++i; } } void func3() { for (int i = 0; i < 1000; ++i) { func1(); func2(); } } int main(){ ProfilerStart("my.prof"); // 指定所生成的profile文件名 func3(); ProfilerStop(); // 结束profiling return 0; }
然后编译链接运行,使用pprof生成分析结果
g++ -o demo demo.cpp -lprofiler -lunwind pprof --text ./demo my.prof > output.txt pprof --pdf ./demo my.prof > output.pdf
查看分析结果,程序是122个时间样本,其中,func1()是40个时间样本,约为400毫秒;func2()是82个时间样本,约为820毫秒。
Total: 122 samples
82 67.2% 67.2% 82 67.2% func2
40 32.8% 100.0% 40 32.8% func1
0 0.0% 100.0% 122 100.0% __libc_start_main
0 0.0% 100.0% 122 100.0% _start
0 0.0% 100.0% 122 100.0% func3
0 0.0% 100.0% 122 100.0% main
|