使用google cpu profiler做性能分析
$ CPUPROFILE=/tmp/profile$ env | grep CPUPROFILE$ export CPUPROFILE$ env | grep CPUPROFILECPUPROFILE=/tmp/profile
?
随便写个程序
double bfunc() { double sum = 0; for (int i = 0; i < 100; ++i) { sum = sum * i; } return sum;}int afunc() { int sum = 0; for (int i = 0; i < 100; ++i) { sum += i; } return sum;}int main() { for (int i = 0; i < 1000000; ++i) afunc(); for (int i = 0; i < 1000000; ++i) bfunc(); return 0;}
编译 ?
gcc -lstdc++ -g ?-finstrument-functions test.cpp -lprofiler
运行./a.out看到
$ ./a.out PROFILE: interrupts/evictions/bytes = 25/0/192
ll /tmp/profile 可以看到产生的输出文件
生成dot文件
$ pprof --dot a.out /tmp/profile Using local file a.out.Using local file /tmp/profile.Removing killpg from all stack traces.digraph "a.out; 2 samples" {node [width=0.375,height=0.25];Legend [shape=box,fontsize=24,shape=plaintext,label="a.out\lTotal samples: 2\lFocusing on: 2\lDropped nodes with <= 0 abs(samples)\lDropped edges with <= 0 samples\l"];N1 [label="__libc_start_main\n0 (0.0%)\rof 2 (100.0%)\r",shape=box,fontsize=8.0];N2 [label="bfunc\n2 (100.0%)\r",shape=box,fontsize=58.0];N3 [label="main\n0 (0.0%)\rof 2 (100.0%)\r",shape=box,fontsize=8.0];N3 -> N2 [label=2, weight=1, style="setlinewidth(2.000000)"];N1 -> N3 [label=2, weight=1, style="setlinewidth(2.000000)"];N2 -> N2 [label=1, weight=1, style="setlinewidth(2.000000)"];}
?把它重定向到b.dot,生成gif,可能会遇到
$ dot -Tgif b -o outfile.gifRenderer type: "gif" not recognized. Use one of: canon cmap cmapx dia dot fig hpgl imap ismap mif mp pcl pic plain plain-ext ps ps2 svg svgz vtx xdot
据说是一个Bug,yum install graph-gd之后就可以了。
也可以在下载源码安装,但是安装的时候提示graphviz的版本也要一致。
没办法重新下个一致的graphviz编译。
需要安装ann-libs等依赖见
http://rpm.pbone.net/index.php3/stat/3/srodzaj/1/search/libANN.so.1
http://www.graphviz.org/Download_linux_rhel.php
需要啥依赖都在rpm search那里搞吧。用个东西真不容易。。
最后终于大功告成
dot -Tgif b.dot -o outfile.gif
可以生成gif图片了。
?
这说明整数的加法相对于浮点数的乘法就是毛毛雨。
调整一下代码
double bfunc() { double sum = 0; for (int i = 0; i < 100; ++i) { sum = sum * i; } return sum;}int afunc() { double sum = 0; for (int i = 0; i < 100; ++i) { sum = sum * i; } return sum;}int main() { for (int i = 0; i < 1000000; ++i) afunc(); for (int i = 0; i < 1000000; ++i) bfunc(); return 0;}
?
?
?这是符合期望的,但是main函数呢?可见main函数体的cpu运行时间太少了。再调整一下
double bfunc() { double sum = 0; for (int i = 0; i < 2; ++i) { sum = sum * i; } return sum;}int afunc() { double sum = 0; for (int i = 0; i < 2; ++i) { sum = sum * i; } return sum;}int main() { for (int i = 0; i < 50000000; ++i) afunc(); for (int i = 0; i < 50000000; ++i) bfunc(); return 0;}
?
看到main函数了,为啥没有边(edges)?发现把之前的-g改成-O2了。。
?
?
g++ -g -lstdc++ test.cpp -lprofiler
sh make.sh./a.outpprof --dot --edgefraction=0.0 a.out /tmp/profile > b.dotdot -Tgif b.dot -o outfile.gif?最后的结果,如果不关心调用关系,只关心每个函数的CPU占用,还是可以把-g换成-O2的。
?
(如果编译加上-finstrument-functions,可以看到内核调用了__cyg_profile_func_exit)
?
?
最后为了用浏览器看到结果,
用tornado(http://www.tornadoweb.org/en/stable/)搭个web服务。
这个还是很使用的,因为很多时候我们在上面的分析可能在远程linux服务器下。
?