使用GPerf工具:不工作,问题是重定向?

时间:2016-03-16 12:57:26

标签: profiler gperftools

我试图对我的软件进行分析以优化它。

我将gprof与编译标记-g -pg -O3一起使用,但结果并没有给我足够的精确度。

这是我的Stacktrace编译:

$: make clean; make;

rm -f ./obj/*.o
rm -f ./bin/mdk-verifier
rm -f ./grammar/modal.output
rm -f ./grammar/modal.tab.h
rm -f ./grammar/*.cpp
rm -f ./lex.backup

bison -d -t -l -v -o ./grammar/modal.tab.c ./grammar/modal.y && mv ./grammar/modal.tab.c ./grammar/modal.tab.cpp
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./grammar/modal.tab.cpp -o ./obj/modal.tab.o
flex -l -b -o./grammar/lex.yy.cpp ./grammar/modal.lex   
g++ -O3 -g -pg -I./include -c ./grammar/lex.yy.cpp -o ./obj/lex.yy.o
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/Kripke.cc -o ./obj/Kripke.o   
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/Term.cc -o ./obj/Term.o 
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/BooleanConstant.cc -o ./obj/BooleanConstant.o 
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/Variable.cc -o ./obj/Variable.o 
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/PropositionalVariable.cc -o ./obj/PropositionalVariable.o 
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/Operation.cc -o ./obj/Operation.o 
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/BooleanOperation.cc -o ./obj/BooleanOperation.o 
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/ModalOperation.cc -o ./obj/ModalOperation.o   
g++ -O3 -g -pg -fPIC -std=c++11  -I./include -c ./src/Formula.cc -o ./obj/Formula.o 
g++ -O3 -g -pg -fPIC -std=c++11  -o ./obj/Main.o -c ./src/Main.cc 
g++ -O3 -g -pg -static -lprofiler -o ./bin/mdk-verifier ./obj/modal.tab.o ./obj/lex.yy.o ./obj/Kripke.o ./obj/Term.o ./obj/BooleanConstant.o ./obj/PropositionalVariable.o ./obj/Variable.o ./obj/Operation.o ./obj/BooleanOperation.o ./obj/ModalOperation.o ./obj/Formula.o ./obj/Main.o               

以下是我打电话给我的节目的方式:

$: ./bin/mdk-verifier ./problem.txt < solution.txt 

所以执行后,一切都很好,我得到一个gmon.out文件。我正在执行命令gprof ./bin/mdk-verifier | more,我得到以下结果:

Each sample counts as 0.01 seconds.
  %   cumulative   self              self     total           
 time   seconds   seconds    calls  ms/call  ms/call  name    
 34.00      2.13     2.13       18   118.33   118.33  ModalOperation::checkBranch(Kripke&, unsigned int)
  ...
  ...
  5.91      4.98     0.37 54684911     0.00     0.00  BooleanOperation::checkBranch(Kripke&, unsigned int)
  4.63      5.27     0.29 54684911     0.00     0.00  PropositionalVariable::checkBranch(Kripke&, unsigned int)

显然,ModalOperation :: checkBranch的调用次数溢出......每次进入此函数时都会显示,我确实做了超过18次调用......

所以我考虑使用另一个分析器,更精确,我发现Google GPerfTools

我想使用它,我安装在我的Ubuntu上:

  • libgoogle-perftools-dev的
  • 谷歌perftools

并按照tutorial,他们让我设置环境变量CPUPROFILE

我做了,我得到了:

 $: env | grep "CPU"
 CPUPROFILE=./prof.out

在我的可执行文件链接过程中我也放了-lprofiler所以我认为一切都还可以,我可以开始分析文件./prof.out中的数据

但不幸的是,这个文件没有出现......没有创建,所以我无法分析任何内容...

有没有人知道为什么没有创建./prof.out文件以及为什么分析不会收集数据?

提前感谢您的帮助!

最诚挚的问候;

1 个答案:

答案 0 :(得分:1)

您的目的是节省软件的时间。多个问题,首先是否定因素:

  • -O3:编译器可以优化某些内容。它不能优化只有你可以优化的东西。它可以做的是通过加扰代码使它们很难找到。使用-O3的时间是之后您找到并修复了的内容。

  • gprof值得尊敬,但更多。它对程序计数器进行采样并计算函数调用。 Here is a list of problems with that. 它会为您提供一个调用图,但speedups can easily hide in that

  • gperftools更好(为了回应Aliaksei的评论而修改),因为它是一个真正的堆栈采样器。通常情况下,它是一个&#34; CPU-profiler&#34;,在这种模式下,任何花在阻塞上的时间都是盲目的,比如I / O或睡眠。但是,如果设置环境变量CPUPROFILE_REALTIME=1,则可以在挂钟时间对其进行采样,因此它将看到I / O,休眠和其他阻塞系统调用。 它有很多输出选项。 它似乎不容易看到实际堆栈样本本身的小随机选择,带有行号信息。

现在是积极的:

  • 许多人使用的方法(不是产品)random pausing。 我们的想法是将质量替换为数量 - 在合适的时间获取堆栈样本 。 在感兴趣的时间间隔期间,很少需要,例如5,10或20。如果某些事情需要95%的时间,那么每个堆栈样本有95%的可能性在正确的时间。 然后检查每个堆栈样本以查看发生了什么 - 不要只是总结/累积/平均/做假装统计。 (如果这是在调试器下手动完成的,您还可以检查数据变量,更加了解程序在该时刻花费的时间。) 对象是找到问题,而不是测量它。 如果您在多个样本上看到它,您可以看到的任何可以避免的东西将节省大量时间。 Here's how much. 您需要两次查看的样本越少,保存的样本就越多。 如果你想确切地看到它为你节省了什么,只需在前后使用秒表。 而且不要只做一次。每当你解决问题时,你都会发现更多问题,所以如果你继续这样做,你可能会得到dramatic speedups