三种Linux性能分析工具的比较

简介:


    无论是在CPU设计、服务器研发还是存储系统开发的过程中,性能总是一个绕不过去的硬指标。很多时候,我们发现系统功能完备,但就是性能不尽如意,这时候就需要找到性能瓶颈、进行优化。首先我们需要结合硬件特点、操作系统和应用程序的特点深入了解系统内部的运行机制、数据流图和关键路径,最好找出核心模块、建立起抽象模型;接着需要利用各种性能分析工具,探测相关模块的热点路径、耗时统计和占比。在这方面,Linux操作系统自带了多种灵活又具有专对性的工具,此外一些厂家也开源了不少优秀的性能分析工具。下面就结合笔者最近对某服务器上IO写性能分析的过程,和大家分享一下对这三种主流工具的使用方法和感受。


1.普通应用程序性能分析的利器 gprof

    gprof能生成CPascalFortan77程序执行时候的调用关系profileprofile里面记录了程序每一次的内部调用关系和耗时。它要求程序在最后的链接阶段制定-pg选项,注意必须是在链接阶段而不是在编译生成.o文件的阶段,否则生成的可执行文件运行后不会生成profile,默认的profile文件名是gmou.out


比如有下面的测试文件:

#include <stdio.h>

#include <string.h>


unsigned long f3(unsigned long cnt)

{

//return cnt*cnt*cnt*cnt*cnt*cnt*cnt;

return cnt*cnt*cnt*cnt*cnt*cnt;

}



unsigned long f2(unsigned long cnt)

{

//return (f3(cnt) ^ f3(cnt + 1)) % cnt;

return (f3(cnt) ^ f3(cnt + 1));

}


unsigned long f1(unsigned long cnt)

{

if (cnt == 0)

return 0;


if (cnt == 1)

return 1;


return (f2(cnt-1)^f2(cnt-2));

}


int main(void)

{

int i, cnt = 40000;


for (i=0;i<cnt;i++)

printf("F1(%d) = %ld\n", i, f1(i));


return 0;

}


    我们可以通过下面的命令生成gmon.out文件:

gcc -c -o test.o test.c

gcc -o -pg test test.c

    执行一次之后,可以看到gmon.out已经生成,可以通过下面的命令,看到每个函数及其调用的函数时间占比和调用次数:

[root@localhost backup]# gprof test gmon.out -p

Flat profile:


Each sample counts as 0.01 seconds.

%  cumulative   self              self     total

time  seconds   seconds    calls  ns/call  ns/call  name

67.37     0.02     0.02   159992   126.32   126.32  f3

33.68     0.03     0.01    79996   126.32   378.97  f2

0.00     0.03     0.00    40000     0.00   757.89  f1


%        the percentage of the total running time of the

time      program used by this function.


cumulative a running sum of the number of seconds accounted

seconds  for by this function and those listed above it.


self     the number of seconds accounted for by this

seconds   function alone.  This is the major sort for this

listing.


calls     the number of times this function was invoked, if

this function is profiled, else blank.


self     the average number of milliseconds spent in this

ms/call   function per call, if this function is profiled,

else blank.


total    the average number of milliseconds spent in this

ms/call   function and its descendents per call, if this

function is profiled, else blank.


name      the name of the function.  This is the minor sort

for this listing. The index shows the location of

the function in the gprof listing. If the index is

in parenthesis it shows where it would appear in

the gprof listing if it were to be printed.


当然,用户还可以用gprof test gmon.out -q或者gprof test gmon.out -l得到更详细的信息:

Call graph (explanation follows)



granularity: each sample hit covers 2 byte(s) for 32.99% of 0.03 seconds


index % time    self  children    called     name

0.01   0.02   79996/79996       f1 [2]

[1]   100.0    0.01    0.02   79996         f2 [1]

0.02   0.00  159992/159992      f3 [4]

-----------------------------------------------

0.00   0.03   40000/40000       main [3]

[2]   100.0    0.00    0.03   40000         f1 [2]

0.01   0.02   79996/79996       f2 [1]

-----------------------------------------------

<spontaneous>

[3]   100.0    0.00    0.03                 main [3]

0.00   0.03   40000/40000       f1 [2]

-----------------------------------------------

0.02   0.00  159992/159992      f2 [1]

[4]     66.7  0.02    0.00  159992         f3 [4]



可以看到,gprof可以根据函数的调用关系,很容易得到相关函数的调用次数和时间占比。美中不足的是它对多线程支持不好,如果需要加入多线程,需要利用gprof-helper.c文件生成libgprof-helper.so

gcc -shared -fPIC gprof-helper.c -o gprof-helper.so -lpthread-ldl

然后cp gprof-helper.so /usr/lib/ /usr/lib64,最后链接到应用程序:

gcc -o test.o -pg -lgprof-helper -lpthread


2.内核和应用程序性能分析的集成工具perf

    除了上面提供的gprof外,google也提供了一款强大的性能分析工具perf,它被广泛应用在内核和应用程序的性能分析当中。目前大部分Linux OS 自带perf工具,使用也很简单,在应用程序执行前,需要指定统计的时间和模式,比如用CPU时间来统计函数运行时间占比:

perf record  -e cpu-clock --call-graph fp ./test


可以看到后面会生成perf.data,使用perf report -v -i perf.data,可以看到libc到内核函数的调用过程和执行时间统计:

wKiom1fsmeOAZpa_AAG3bhEEwhM924.png

从上面的图可以看到printf()占了整体执行时间的3.8%,剩下的大部分时间都是在内核里面。


3.专业人士的瑞士军刀 stap - systemtap

    systemtap能把stap脚本语言翻译成C代码,并把这些生成的代码加入到内核模块,或者利用动态代码插桩的方式加入加入到应用程序执行的过程中,和perf一样,它也不用修改任何代码,就能得到期望的统计信息。除此之外,它还能在程序执行的过程中打印内核或者应用程序中的参数或变值。


比如在内核中,我们可以用systemtap的前端工具stap写脚本来打印iSCSI驱动中的一个参数信息:

[root@localhost perf]# cat d2.stp

probe module("iscsi_target_mod").function("iscsi_target_locate_portal")

{

printf("iSCIS initiator login: %s\n", kernel_string($login->req_buf));

}

参考下面的命令运行stap脚本:

[root@localhost perf]# stap d2.stp -v

Pass 1: parsed user script and 117 library script(s) using 223476virt/40972res/3064shr/38364data kb, in 170usr/20sys/212real ms.

Pass 2: analyzed script: 1 probe(s), 2 function(s), 0 embed(s), 0 global(s) using 225668virt/44044res/3936shr/40556data kb, in 50usr/220sys/282real ms.

Pass 3: translated to C into "/tmp/stapXY9W47/stap_482377c0eab312aca9dcd34efac51d67_2620_src.c" using 225668virt/44400res/4276shr/40556data kb, in 50usr/220sys/268real ms.

Pass 4: compiled C into "stap_482377c0eab312aca9dcd34efac51d67_2620.ko" in 5000usr/1120sys/6094real ms.

Pass 5: starting run.

iSCIS initiator login: InitiatorName=iqn.1991-05.com.microsoft:dell-pc

可以看到上面在target端打印出了initiatorIQN名称。


同样我们也可以在应用程序中用到stap,还是以上面的./test程序为例,可以用下面的stap脚本来统计test执行过程中f1函数占用的时间:


[root@localhost ~]# cat test.stp

# path of zfs-fuse should be take care

#

# usage: stap test.stp -v -x `pidof test`


global f1, f1_intervals;


probe process("/root/test").function("f1")

{

f1[tid()] = gettimeofday_us()

}


probe process("/root/test").function("f1").return

{

t = gettimeofday_us()

old_t = f1[tid()]

if (old_t) f1_intervals  <<< t - old_t

delete f1[tid()]

}


probe end

{

if (@count(f1_intervals)) {

printf("zvol_log_write latency min:%dus avg:%dus max:%dus count:%d\n",

@min(f1_intervals), @avg(f1_intervals), @max(f1_intervals),

@count(f1_intervals))

print(@hist_log(f1_intervals));

}


}

[root@localhost ~]# stap test.stp -v -x `pidof test`


wKioL1fsmmHBe-YCAABxgCeq_Mw379.png

可以看到stap统计的精度非常之高,f1()函数执行时间在1us17us之间。


4.三种工具的比较分析

    通过上面基于test.c用三种性能分析工具运行的过程和结果可以看到,gporfperf适合对整个应用程序所有的函数进行批量处理,而stap很小微,能够轻易测量到某个函数或者某组函数的执行时间、乃至运行时修改程序里的变量。三种工具的分析比较如下:



实现原理

前端工具

后端工具

时间精度

多线程支持

界面友好度

批量处理

应用场景

gprof

链接时插桩

gprof

粗粒度,默认0.01s

要额外链接

gprof-helper.so

应用程序热点分析、时间占比统计

perf

运行时插桩

perf record

Perf report

细粒度,CPU clock

较好

全系统热点定位、CPU性能分析

stap

运行时插桩

stap

systemtap

细粒度,1us

特定模块、函数耗时测量、精确调优


     因此,在今后的性能优化工作过程中,如果碰到一个不太熟悉和了解的系统,我们可以先用perf(没有源代码的情况)、gprof(有源代码的情况)快速定位热点函数和模块,然后针对热点模块用stap进行测量相关函数的具体时间分布,按照这种自顶向下的思路能够快速找到要害、对症下药。而对于我们已经熟悉的模块或者已知的瓶颈,就可以直接用stap进行分析了,这样能提高效率。


5.参考文献和资料

http://sam.zoy.org/writings/programming/gprof.html

https://en.wikipedia.org/wiki/DynInst

http://blog.csdn.net/u010838822/article/details/14094287



























本文转自存储之厨51CTO博客,原文链接: http://blog.51cto.com/xiamachao/1857696,如需转载请自行联系原作者







相关文章
|
2月前
|
安全 Linux Shell
四、Linux核心工具:Vim, 文件链接与SSH
要想在Linux世界里游刃有余,光会“走路”还不够,还得配上几样“高级装备”。首先是Vim编辑器,它像一把瑞士军刀,让你能在命令行里高效地修改文件。然后要懂“软硬链接”,软链接像个快捷方式,硬链接则是给文件起了个别名。最后,SSH是你的“传送门”,不仅能让你安全地远程登录服务器,还能用scp轻松传输文件,设置好密钥更能实现免-密登录,极大提升效率。
369 3
|
6月前
|
Linux 开发工具
7种比较Linux中文本文件的最佳工具
7种比较Linux中文本文件的最佳工具
7种比较Linux中文本文件的最佳工具
|
2月前
|
安全 Linux iOS开发
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
180 0
SonarQube Server 2025 Release 5 (macOS, Linux, Windows) - 代码质量、安全与静态分析工具
|
2月前
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
270 16
|
4月前
|
缓存 监控 Linux
Linux系统性能调优技巧和相关工具
Linux 作为一种应用应展和系统服务的优选操作系统,在处理性能和端到端点评估上持有出色表现。但是,在处理进程或系统处于低效状态时,性能调优就显得十分重要。本文将探讨一些 Linux 系统性能调优的常用技巧,并介绍相关工具
148 1
Linux系统性能调优技巧和相关工具
|
4月前
|
Linux 数据安全/隐私保护 iOS开发
推荐Linux环境下效能优良的双向文件同步工具
综合上述条件,对于Linux环境下的双向文件同步需求,Unison 和 Syncthing 是两个非常出色的选择。它们都有良好的社区支持和文档资源,适用于不同规模的环境,从个人使用到商业部署。Unison 特别适合那些需要手动干预同步过程、需要处理文件冲突解决的场景。而 Syncthing 更加现代化,适合需要自动、实时的数据同步与备份的环境。对于选择哪一个,这将取决于个人的使用场景和具体需求。
514 16
|
3月前
|
数据采集 编解码 运维
一文讲完说懂 WowKey -- WowKey 是一款 Linux 类设备的命令行(CLT)运维工具
WowKey 是一款面向 Linux 类设备的命令行运维工具,支持自动登录、批量执行及标准化维护,适用于企业、团队或个人管理多台设备,显著提升运维效率与质量。
|
6月前
|
Ubuntu 搜索推荐 Linux
详解Ubuntu的strings与grep命令:Linux开发的实用工具。
这就是Ubuntu中的strings和grep命令,透明且强大。我希望你喜欢这个神奇的世界,并能在你的Linux开发旅程上,通过它们找到你的方向。记住,你的电脑是你的舞台,在上面你可以做任何你想做的事,只要你敢于尝试。
375 32
|
8月前
|
自然语言处理 数据库 iOS开发
DBeaver Ultimate Edtion 25.0 Multilingual (macOS, Linux, Windows) - 通用数据库工具
DBeaver Ultimate Edtion 25.0 Multilingual (macOS, Linux, Windows) - 通用数据库工具
598 12
DBeaver Ultimate Edtion 25.0 Multilingual (macOS, Linux, Windows) - 通用数据库工具