分类: LINUX
2014-11-23 20:43:56
Linux下的两款性能调试工具
Valgrind 概述
Valgrind是一套Linux下开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。Valgrind的体系结构如下图所示:
图1 Valgrind 体系结构
Valgrind包括如下一些工具:
(1) memcheck: 这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。使用格式为valgrind
--tool=memcheck
--leak-check=yes
(2) callgrind: 它主要用来检查程序中函数调用过程中出现的问题,可以统计出耗时最长的功能段或代码段,从而进行性能调优。使用格式为valgrind
--tool=callgrind
(3) cachegrind: 它主要用来检查程序中缓存使用出现的问题,可用来降低程序的cache miss rate,同时减少memory
reference。使用格式为valgrind
--tool=cachegrind
(4) helgrind: 它主要用来检查多线程程序中出现的竞争问题,是多线程编程的福音。使用格式为valgrind
--tool=helgrind
(5) massif: 它主要用来检查程序中堆栈使用中出现的问题。使用格式为valgrind
--tool=massif
(6) extension: 可以利用core提供的功能,自己编写特定的内存调试工具。
memcheck内存检查原理
memcheck
能够检测出内存问题,关键在于其建立了两个全局表,如图2所示。
图2 内存检查原理
(1)Valid-Value 表:
对于进程的整个地址空间中的每一个字节(byte),都有与之对应的 8 个 bits;对于 CPU 的每个寄存器,也有一个与之对应的 bit 向量。这些 bits 负责记录该字节或者寄存器值是否具有有效的、已初始化的值。
(2)Valid-Address 表:
对于进程整个地址空间中的每一个字节(byte),还有与之对应的1个bit,负责记录该地址是否能够被读写。
(3)检测原理:
当要读写内存中某个字节时,首先检查这个字节对应的 A bit,如果该A bit显示该位置是无效位置,memcheck 则报告读写错误。内核(core)类似于一个虚拟的 CPU 环境,这样当内存中的某个字节被加载到真实的CPU中时,该字节对应的 V bit 也被加载到虚拟的CPU环境中。一旦寄存器中的值被用来产生内存地址,或者该值能够影响程序输出,则 memcheck会检查对应的V bits,如果该值尚未初始化,则会报告使用未初始化内存错误。
Perf 概述
Perf 是用来进行软件性能分析的工具。通过它,应用程序可以利用PMU、tracepoint 和内核中的特殊计数器来进行性能统计。它不但可以分析指定应用程序的性能问题 (per thread),也可以用来分析内核的性能问题,当然也可以同时分析应用代码和内核,从而全面理解应用程序中的性能瓶颈。
Perf 的常用工具如下:
(1)pref list
使用perf list命令可以列出所有能够触发perf 采样点的事件。
(2)perf stat
使用格式:perf stat
perf stat 中几个最常用的统计信息:
Task-clock-msecs:CPU 利用率,该值高,说明程序的多数时间花费在CPU计算上而非IO。
Context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的。
Cache-misses:程序运行过程中总体的cache利用情况,如果该值过高,说明程序的cache利用不好。
CPU-migrations:表示进程运行过程中发生了多少次CPU迁移,即被调度器从一个CPU转移到另外一个CPU上运行。
Cycles:处理器时钟,一条机器指令可能需要多个cycles。
Instructions: 机器指令数目。
IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性。
Cache-references: cache 命中的次数
Cache-misses: cache失效的次数。
(3)perf top
有些时候,我们只是发现系统性能无端下降,并不清楚究竟到底是哪个进程导致的。此时需要一个类似 top 的命令,列出所有值得怀疑的进程,从中找到需要进一步审查的家伙。Perf top 用于实时显示当前系统的性能统计信息。该命令主要用来观察整个系统当前的状态,比如可以通过查看该命令的输出来查看当前系统最耗时的内核函数或某个用户进程。
(4)perf record和perf report
使用格式:
perf record –e
cpu-clock
perf report
使用 top 和 stat 之后,你可能已经大致有数了。要进一步分析,便需要一些粒度更细的信息。比如说已经断定目标程序的计算量较大,也许是因为有些代码写的不够精简。那么面对长长的代码文件,究竟哪几行代码需要进一步修改呢?这便需要使用 perf record 记录单个函数级别的统计信息,并使用 perf report 来显示统计结果。此外,调优应该将注意力集中到百分比高的热点代码片段上。
总结
此外,还有另外两种比较常用的性能调试工具Oprofile和Gprof,Perf是在Oprofile的基础之上改进过来的,无论从易用上来说还是功能上,Perf都明显优于Oprofile。经过实测,如果内核已经支持了Perf, 强烈推荐使用Perf;如果内核不好支持,或者支持麻烦,可考虑使用Valgrind进行测试,Gprof可以完全被Valgrind代替,且Valgrind的结果比Gprof更准确全面一些。