计算机 · 2021年12月18日 0

C语言性能调优

记录一下最近使用过的程序性能分析工具的使用方法,免得以后需要的时候又得Google、百度。

参考博客

gprof

  • 优点 GNU Bintuils的一部分。都不需要什么多余的安装步骤。轻量级。速度快。
  • 缺点
    1. ~~据说使用的技术很过时。~~反正从我的实际使用经验来看问题在于计时的粒度太大。
    2. 需要有源码重新编译程序,最终运行的程序是插入了性能统计代码的程序。
    3. 不支持多线程。
    4. 不能分析共享库(因为不可能重新加上-pg选项来重新编译共享库)。

简单教程

1. 编译程序时需要加上额外的-pg选项;

使用gcc编译的时候需要加上这个-pg选项,编译器才会在程序里加入性能统计的代码。如果编译过程是分步进行的,比如先分别编译每个源文件为可重定位目标文件,然后再链接成为可执行目标文件的话,那么在链接的命令里也需要加入-pg选项,而不仅只是在单独编译每个源文件时加上-pg选项。比如官网举的例子是:

cc -g -c myprog.c utils.c -pg
cc -o myprog myprog.o utils.o -pg

有的时候需要在编译的时候使用-static选项,让编译器插入的性能统计的代码静态链接相应的库,以避免编译环境和运行环境使用不同的共享库导致编译好的程序不能运行。

2. 执行程序

执行编译好的包含了性能统计代码的程序。程序运行结束之后会生成一个gmon.out文件。程序必须正常结束(从main返回或者调用exit),才会生成有效的gmon.out文件。

3. 查看统计结果

使用gprof程序处理生成的gmon.out文件,得到一个关于程序性能统计的报告:

  gprof options [executable-file [profile-data-files...]] [> outfile]

报告里包含了函数的调用关系,每个函数被调用了多少次,花了多少时间等信息。更详细的关于gprof的控制选项,可以查看其manual。

valgrind/callgrind

  • 优点
    • 不需要重新编译程序。
    • 支持多线程。
    • 支持共享库的分析。
  • 缺点 相比gprof会占用更多资源。由于valgrind使用类似虚拟机的工作方式,速度比gprof慢了几十倍。

简单教程

1.正常编译程序 2.使用valgrind运行程序:

valgrind --too=callgrind ./cpuload

3.运行完之后会生成一个叫profile.callgrind之类名字的文件。

4.用一个叫kcachegrind的程序打开上一步生成的文件。可自行探索UI界面,看可以获取到哪些信息,反正比gprof的更多更详细,而且UI界面也特别美观。

gperftools

大概就是升级版的gprof。由于我觉得valgrind/callgrind已经能够很好地满足自己的要求,所以就没再细看。有兴趣的看原博客相关介绍。