GCC的“-pg”标志如何与分析器相关联?

37

我正在尝试理解使用GCC编译C代码时,-pg(或-p)标志的工作原理。

官方的GCC文档仅说明

-pg生成额外的代码以编写适用于分析程序gprof的配置文件信息。您必须在编译要获取数据的源文件时使用此选项,并且在链接时也必须使用它。

这真的很有趣,因为我正在进行关于分析器的小型研究。我正在尝试选择最适合该工作的工具。

3个回答

31

使用 -pg 编译选项可以对您的代码进行仪器化处理,这样 Gprof 就可以提供详细信息报告。请参见 gprof 的手册,第 9.1 节:分析实现

分析是通过更改程序中每个函数的编译方式来实现的,这样当它被调用时,就会存储有关其调用位置的一些信息。从这里,分析器可以确定是哪个函数调用了它,并计算它被调用的次数。编译程序时使用 -pg 选项进行此更改,这将导致每个函数作为其最初操作之一调用 mcount(或者根据操作系统和编译器的不同还可能是 _mcount__mcount)。

分析库中包含的 mcount 子程序负责将其父子例程(即子例程和其父例程)记录在内存中的调用图表中。通常,这是通过检查堆栈帧来找到子程序的地址和原始父程序中的返回地址来完成的。由于这是一个非常依赖于机器的操作,因此 mcount 本身通常是一个短汇编语言存根子程序,它提取所需的信息,然后使用两个参数 - frompcselfpc 调用 __mcount_internal(一个普通的C函数)。__mcount_internal 负责维护内存中的调用图表,记录每个调用弧的 frompcselfpc 和被遍历的次数。

...

请注意,使用这种仪器化分析器进行分析时,您正在分析与无分析仪器相同的代码。仪器化代码本身会带来额外的开销。此外,仪器化代码可能会改变指令和数据缓存的使用情况。

与工具化的分析器不同,像Intel VTune这样的采样分析器通过使用操作系统中断定期检查目标程序计数器来处理未被工具化的代码。它还可以查询特殊的CPU寄存器,以便更深入地了解正在发生的情况。

此外,参见分析器工具化 Vs 采样


9

这个链接简要介绍了gprof的工作原理。

这个链接对其进行了广泛的批评。 (查看我对存档问题的回答。)


自从阅读了这些内容以后,我一直在使用 gdb 中的断点和回溯来进行速度分析。 - David Stone
@David:我对此有很多争议,但我用它做了这个例子。速度提升了700倍。我不会说暂停很漂亮,但我不知道还有其他方法可以得到这样的结果。 - Mike Dunlavey
@duedl0r:更新了链接。 - Mike Dunlavey
需要提供不仅仅是链接的答案。 - Peter Mortensen

0

来自"使用Ftrace测量函数持续时间":

仪器分为两种主要形式——显式声明的跟踪点和隐式跟踪点。

显式跟踪点由开发人员定义的声明组成,它们指定跟踪点的位置以及关于在特定跟踪站点收集哪些数据的其他信息。隐式跟踪点是由编译器自动放置到代码中的,这要么是由于编译器标志,要么是由于开发人员重新定义常用宏。

要隐式地检测函数,当内核配置为支持函数跟踪时,内核构建系统会将-pg添加到与编译器一起使用的标志中。这会导致编译器向每个函数的序言添加代码,调用一个名为mcount的特殊汇编例程。此编译器选项专门用于性能分析和跟踪目的。


相关:*答案完全复制但已经正确引用* - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接