我试图对我的软件进行分析以优化它。
我将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上:
并按照tutorial,他们让我设置环境变量CPUPROFILE
我做了,我得到了:
$: env | grep "CPU"
CPUPROFILE=./prof.out
在我的可执行文件链接过程中我也放了-lprofiler
所以我认为一切都还可以,我可以开始分析文件./prof.out
中的数据
但不幸的是,这个文件没有出现......没有创建,所以我无法分析任何内容...
有没有人知道为什么没有创建./prof.out
文件以及为什么分析不会收集数据?
提前感谢您的帮助!
最诚挚的问候;
答案 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,休眠和其他阻塞系统调用。
它有很多输出选项。
它似乎不容易看到实际堆栈样本本身的小随机选择,带有行号信息。
现在是积极的: