一、gprof的概述
gprof是一种使用逆向工程的方法来分析程序性能的工具。一般用来分析函数的耗时,包括哪些函数被调用多少次及执行时间,以及函数之间的调用关系等等。
正如可以使用GNU GCC编译器中的 -pg
选项来生成 profil 数据文件一样,gprof 也会读取这个文件并进行分析。gprof 将会生成一个程序的性能概览报告,包括耗时比例和函数调用关系。在可视化的表格形式中,直观展示出程序运行的时间。
二、gprof基本用法
下面是一个简单的C++代码示例:
#include <iostream>
#include <cstdlib>
using namespace std;
void functionC();
void functionB();
void functionA();
int main(int argc, char* argv[])
{
for(int i=0;i<500;i++)
{
functionA();
}
return 0;
}
void functionA()
{
functionB();
functionC();
}
void functionB()
{
int t = rand()%10000;
for(int i=0;i < t; i++);
}
void functionC()
{
int t = rand()%50000;
for(int i=0;i < t; i++);
}
为了生成 gprof 报告,首先需要编译主程序,使用 -pg
选项来生成 profiler 数据文件。
g++ -pg main.cpp -o my_app
然后运行程序:
./my_app
在运行后,gprof 所需的数据文件 my_app.gmon
会被生成。
最后使用 gprof 来分析程序:
gprof my_app
gprof 将生成一个报告文件 gprof 输出给标准输出。也可以通过 -b
选项将其输出到一个文件中,如:
gprof my_app -b report.txt
三、gprof的输出内容
gprof 的输出可以分为两部分。第一部分是概述部分,它展示了程序的总体运行情况,包括总运行时间、每个函数运行时间、每个函数运行所占百分比、以及一个简单的调用图示例。以下是输出的示例:
flat % cum %
...
6.02 28.00% 18.98 88.15% functionC
2.96 13.70% 2.96 13.70% functionB
9.56 44.30% 28.94 134.06% functionA
...
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ms/call ms/call name
23.14 26.34 26.34 1 26340.00 26340.00 functionB
29.17 47.73 21.39 1 21390.00 21390.00 functionC
47.49 100.00 52.27 1 52270.00 52270.00 functionA
在这个示例中,我们可以看到 3 个函数的概述信息和详细信息。每个函数的详细信息包括运行时间、被调用次数,以及被调用的总时间。需要注意的是,调用时间是递归地计算的。即如果函数 A 调用 B,B 调用 C,那么调用 A 的时间将包含 A、B、C 的总时间。 例如,在这个示例中,函数 A 的运行时间是 28.94 s,其中包括函数 B 和 C 的时间。由于函数 A 调用了 B 和 C,所以被调用的总时间是 52.27 s。另外,由于函数 B 和 C 都是 A 调用的,所以它们的累计时间也包含在 A 的总时间中。
四、gprof配置参数
除了 -pg
选项外,gprof 还可以接受其他一些参数来控制其行为。
-p
参数用来控制输出的详细程度。其值可以是NONE
、FLAT
、GRAPH
或ALL
。默认是FLAT GRAPH
。-a
和-q
选项用来忽略或包含所有函数,包括静态函数。默认情况下,gprof 会跳过静态函数。-S
参数可以用来指定汇编源代码,以便 gprof 可以在汇编级别计算函数调用关系和时间。
五、优化代码以使用 gprof
在编写代码时,可以使用一些技巧来优化程序以便更好地使用 gprof。以下是一些提示:
- 添加调试信息。gprof 会分析程序中函数间的调用关系,添加足够详细的调试信息将会使报告更准确。例如,使用
-g
选项编译程序可以在可执行文件中添加调试信息。 - 减小程序规模。如果程序很大,gprof 将会分析所有函数,这会耗费大量时间和空间。因此,在进行性能分析时应该只分析感兴趣的部分或者将程序分解为更小的部分。
- 避免函数重复调用。如果同一个函数被多次调用,gprof 将会将其计算多次,这会导致时间的重复记录。因此,在程序设计时应该避免这种情况。一种可能的解决方法是将被重复调用的函数内联,这样gprof就无需记录其调用。
六、结论
gprof 是一种强大的性能分析工具,可以用来分析程序的性能瓶颈和调试错误。通过使用gprof来分析程序,能够得出程序的函数耗时比例和函数调用关系。但是需要注意的是,gprof 的分析结果取决于所使用的硬件和操作系统等环境因素。