您当前的位置:首页 > 电脑百科 > 站长技术 > 服务器

性能分析利器之perf浅析

时间:2019-11-11 09:46:00  来源:  作者:

源:http://walkerdu.com/2018/09/13/perf-event/

作为服务器后台开发,不仅仅要写业务逻辑,后台意味着高并发,稳定性,当你写了很多逻辑,发现性能有问题的时候,也要学会性能分析,进行性能优化, 也许你会接触很多性能分析工具:valgrind,gperftools,gprof, oprofile, 有时间慢慢一一介绍,在学习perf的过程中,也学习和加深了很多之前的知识,本文抛砖引玉,希望能帮助大家了解一些性能分析更深的一些东西。

1. perf简介

perf是一款linux内置的性能分析工具,随着内核发布,也被称为perf_events, perf tools, PCL(Performance Counters for Linux), 发布于Linux kernel version 2.6.31, perf是怎么工作的呢?perf如何使用?本文是来介绍一下。

perf官方wiki的介绍是:Linux profiling with performance counters

Perf可以解决高级性能和故障排除,它可以分析(当然目前我也只是用来进行cpu性能分析):

  • 为什么内核消耗CPU高, 代码的位置在哪里?
  • 什么代码引起了CPU 2级cache未命中?
  • CPU是否消耗在内存I/O上?
  • 哪些代码分配内存,分配了多少?
  • 什么触发了TCP重传?
  • 某个内核函数是否正在被调用,调用频率多少?
  • 线程释放CPU的原因?

2. perf的event

它可以利用CPU performance counters(性能计数器),tracepoints, kprobes和uprobes来进行应用程序的性能分析。perf使用这些linux内核提供的tracing特性进行事件的采集和分析,perf使用的event主要有以下几种:

  • Hardware Events: CPU中的寄存器含有performance counters(性能计数器),用来统计 Hardware event,例如 cpu-cycles、instructions executed 、cache-misses、branch mispredicted等。这些event构成了应用程序profiling的基础。
  • Software Events: 基于内核计数器的低优先级events, 例如, CPU migrations(处理器迁移次数), minor faults(soft page faults), major faults(hard page faults).
  • Tracepoints: 是散落在内核源代码中的一些 hook,用来调用probe函数,开启后,它们便可以在特定的代码被运行到时被触发,这一特性可以被各种 trace/debug 工具所使用。Perf 就是该特性的用户之一。假如您想知道在应用程序运行期间,内核内存管理模块的行为,便可以利用潜伏在 slab 分配器中的 tracepoint。当内核运行到这些 tracepoint 时,便会通知 perf。
  • Dynamic Tracing: probe函数(探针or探测函数),kprobe(kernel probe)内核态探针,用来创建和管理内核代码中的探测点。Uprobes,user-probe,用户态探针,用来对用户态应用程序进行探测点的创建和管理,关于kprobe和uprobe可参考对应的内核文档
  • perf使用的event来源,如下图:来源:brendangregg
性能分析利器之perf浅析

 

3. 安装

两种安装方式

  • 通过包管理进行安装,perf工具在 linux-tools-common工具包里,通过包管理软件安装的时候还需要依赖linux-tools-kernelversion包
  • 源码编译:找到对应内核版本的源码包,在tools/perf目录下进行编译

4. 背景

要想使用perf来分析应用程序,需要了解一些基础概念,例如符号表, frame pointer等信息

4.1 符号表

应用程序的符号表,用来将逻辑地址翻译成对应的函数和变量名,这样才能被程序员阅读和分析,没有符号表,profile的结果都是一些16进制的逻辑地址:

如下是perf report分析sshd进程的堆栈调用情况(来自brendangregg):

 

性能分析利器之perf浅析

 

 

对于通过软件包安装的程序,通常都会有dubug package(-dbgsym)即带有符号表信息的程序,如果是源码安装的就需要编译时开启debug选项。

通过使用openssh-server-dbgsym and libc6-dbgsym,sshd的perf report分析结果如下:

性能分析利器之perf浅析

 

4.2 栈回溯(栈展开)

我们经常在编译的时候会开启frame pointers优化选项,即优化掉函数栈帧rbp,省略掉frame pointer是编译器一个很烂的优化,它会破坏debug, 更烂的是省略frame pointer一般是编译器默认的优化选项。

没有frame pointer会使perf 无法获取完整的调用栈,如下示例:

性能分析利器之perf浅析

 

例如上面代码正常不开启优化的编译,进行profile是可以看到call graph的,如下:

性能分析利器之perf浅析

 

如果编译时开启-fomit-frame-pointer(这里因为测试代码简单,直接开优化的话就优化没了),就无法获取到call graph

性能分析利器之perf浅析

 

有三种方法可以修复这个问题,这里不做展开,这些stack walking techniques后面可以写一篇单独的文章:

  • using dwarf data to unwind the stack, 实际上很多profile工具:gperftools, valgrind都是依赖于libunwind,通过dwarf来进行stack trace的
  • using last branch record (LBR) if available (a processor feature)
  • returning the frame pointers

5. 使用

perf提供了一系列的命令来分析程序,如下:

sub command功能说明

annotate 读取perf.data(由perf record生成)显示注释信息,如果被分析的进程含义debug符号信息,则会显示汇编和对应的源码,否则只显示汇编代码

archive 根据perf.data(由perf record生成)文件中的build-id将相关的目标文件打包,方便在其他机器分析

bench perf提供的基准套件的通用框架,可以对当前系统的调度,IPC,内存访问进行性能评估

buildid-cache 管理build-id,管理对于的bin文件

buildid-list 列出perf.data中的所以buildids

data 把perf.data文件转换成其他格式diff读取多个perf.data文件,并给出差异分析

evlist 列出perf.data中采集的事件列表

kmem 分析内核内存的使用kvm分析

kvm 虚拟机上的guest os

list 列出当前系统支持的所有事件名,可分为三类:硬件事件、软件事件,检查点

lock 分析内核中的锁信息,包括锁的争用情况,等待延迟等

record 对程序运行过程中的事件进行分析和记录,并写入perf.data

report 读取perf.data(由perf record生成) 并显示分析结果

sched 针对调度器子系统的分析工具。

script 读取perf.data(由perf record生成),生成trace记录,供其他分析工具使用

stat 对程序运行过程中的性能计数器进行统计

test perf对当前软硬件平台进行健全性测试,可用此工具测试当前的软硬件平台是否能支持perf的所有功能。

timechart 对record结果进行可视化分析输出,record命令需要加上timechart记录

top 对系统的性能进行分析,类型top命令,当然可以对单个进程进行分析

probe 用于定义动态检查点。

trace 类似于strace,跟踪目标的系统调用,但开销比strace小

perf的使用大体可以有三种方式:

  • Counting:统计的方式,统计事件发生的次数,这种方式不生成perf.data文件,例如perf stat, perf top
  • Sampling:采样的方式,采样事件,并写入到内核buffer中,并异步写入perf.data文件中,perf.data文件可以被perf report或者perf script 命令读取。
  • bpf programs on events(https://www.ibm.com/developerworks/cn/linux/l-lo-eBPF-history/index.html)

5.1. perf list

perf list命令可以列出当前perf可用的事件:

cpu-cycles OR cycles [Hardware event]
instructions [Hardware event]
cache-references [Hardware event]
cache-misses [Hardware event]
branch-instructions OR branches [Hardware event]
branch-misses [Hardware event]
bus-cycles [Hardware event]
stalled-cycles-frontend OR idle-cycles-frontend [Hardware event]
stalled-cycles-backend OR idle-cycles-backend [Hardware event]
ref-cycles [Hardware event]
alignment-faults [Software event]
bpf-output [Software event]
context-switches OR cs [Software event]
cpu-clock [Software event]
cpu-migrations OR migrations [Software event]
dummy [Software event]
emulation-faults [Software event]
major-faults [Software event]
minor-faults [Software event]
page-faults OR faults [Software event]
task-clock [Software event]
msr/tsc/ [Kernel PMU event]
rNNN [Raw hardware event descriptor]
cpu/t1=v1[,t2=v2,t3 ...]/modifier [Raw hardware event descriptor]
(see 'man perf-list' on how to encode it)
mem:<addr>[/len][:access] [Hardware breakpoint]

这些事件可以分为三类(在文章开始介绍perf工作原理的时候也说了):Hardware EventSoftware eventTracepoint event.

每个具体事件的含义在perf_event_open的man page中有说明:

  • cpu-cycles:统计cpu周期数,cpu周期:指一条指令的操作时间。
  • instructions: 机器指令数目
  • cache-references: cache命中次数
  • cache-misses: cache失效次数
  • branch-instructions: 分支预测成功次数
  • branch-misses: 分支预测失败次数
  • alignment-faults: 统计内存对齐错误发生的次数, 当访问的非对齐的内存地址时,内核会进行处理,已保存不会发生问题,但会降低性能
  • context-switches: 上下文切换次数,
  • cpu-clock: cpu clock的统计,每个cpu都有一个高精度定时器
  • task-clock :cpu clock中有task运行的统计
  • cpu-migrations:进程运行过程中从一个cpu迁移到另一cpu的次数
  • page-faults: 页错误的统计
  • major-faults:页错误,内存页已经被swap到硬盘上,需要I/O换回
  • minor-faults :页错误,内存页在物理内存中,只是没有和逻辑页进行映射

5.2. perf stat

perf stat可以对程序运行过程中的性能计数器(包括Hardware,software counters)进行统计,分析程序的整体消耗情况:

$perf stat ls
Performance counter stats for 'ls':
 2.164836 task-clock (msec) # 0.808 CPUs utilized 
 51 context-switches # 0.024 M/sec 
 4 cpu-migrations # 0.002 M/sec 
 333 page-faults # 0.154 M/sec 
 5506056 # 2.543 GHz 
 0 stalled-cycles-frontend # 0.00% frontend cycles idle 
 0 stalled-cycles-backend # 0.00% backend cycles idle 
 6100570 instructions # 1.11 insns per cycle 
 1298744 branches # 599.927 M/sec 
 18509 branch-misses # 1.43% of all branches 
 0.002679758 seconds time elapsed

具体各个字段的含义在perf list中已经列出了,这里分析一下重要的数据:

  • task-clock (msec): cpu处理task所消耗的时间,单位ms,0.808 CPUs utilized的表示cpu使用率为80.8% = 2.164836 / 2.679758. 该值越高代表程序是CPU bound而非IO bound 类型。
  • instructions:执行的指令条数, insns per cycle: 即IPC,每个cpu周期执行的指令条数,1.11 = 6100570(instructions) / 5506056(cycles),IPC比上面的CPU使用率更能说明CPU的使用情况,关于IPC有一篇brendangregg的文章,很好的说明CPU使用率不是一个很好的性能分析指标
  • stalled-cycles-frontend和stalled-cycles-backend表示CPU停滞统计,具体可参考

perf stat可以加上-e选项来设置自己关心的事件统计,具体参数可以通过上面的perf list来查看

5.3. perf top

perf top类似系统的命令top,可以实时的查看当前系统各个进程的各个函数的性能计数分析:$sudo perf top

性能分析利器之perf浅析

 

perf top的和perf record的功能参数差不多,我们可以加上-e:来统计特定的event,-g: 开启call-graph, -p:分析特定的进程

平常我们用的更多的是perf record,因为它可以将profiler的结果输出到文件,然后通过perf report来进行分析,或者通过可视化工具进行分析和输出。所以下面着重介绍perf record

5.4. perf record

perf reord可以运行一个命令,但更多的是对已运行的进程进行性能分析,并将分析结果输出到perf.data(默认该文件名)中。不会像perf top一样实时输出分析结果。输出perf.data可以通过perf report进行分析,或者通过perf script输出结果给第三方输出可视化的视图。用前面的示例代码进行测试如下:

$perf record -g -F 99 ./a.out
$perf report
性能分析利器之perf浅析

 

perf record几个总要参数说明一下:

  • -F: 事件采样的频率, 单位HZ, 更高的频率会获得更细的统计,但会带来更多的开销
  • -g: 进行堆栈追踪,生成调用关系图,等价于–call-graph, 默认情况下,-g等同于–call-graph fp,即通过frame pointer来进行堆栈追踪。 如果frame pointer被优化掉的话,可以通过dwarf, lbr进行堆栈追踪
  • sleep: 采样的时间

5.5. perf可视化分析

perf 提供了内置的可视化分析工具 perf timechart,例如:

$perf timechart record ./a.out
$perf timechart
性能分析利器之perf浅析

 

perf timechart输出的是进程运行过程中系统调度的情况,无法对程序的具体代码段进行性能分析,但可以看出总结运行情况:running,idle,I/O等,

Brendangregg写了两款对perf采样结果进行可视化分析的开源工具:Flame Graphs和HeatMap. FlameGraphs即所谓的火焰图,是大家使用比较多的工具,能清晰的展示程序各个函数的性能消耗。HeatMap可以从采样数据中的延迟数据来进行消耗展示。

下面是对之前实例代码的采样数据perf.data进行FlameGraphs的绘制:

$perf script |./stackcollapse-perf.pl|./flamegraph.pl > fg_output.svg
性能分析利器之perf浅析

 

perf_flamegraph.png

6. 参考

Perf官方wiki

https://perf.wiki.kernel.org/index.php/Main_Page

Perf 维基百科

https://en.wikipedia.org/wiki/Perf_(Linux)

Perf – Linux下的系统性能调优工具,第 1 部分

https://www.ibm.com/developerworks/cn/linux/l-cn-perf1/index.html

Linux 效能分析工具: Perf

http://wiki.csie.ncku.edu.tw/embedded/perf-tutorial

Linux内核调试技术——kprobe使用与实现

https://blog.csdn.net/luckyApple1028/article/details/52972315

内核uprobes使用介绍

https://blog.csdn.net/badu_123/article/details/8302642

perf Examples

http://www.brendangregg.com/perf.html

火焰图的使用

http://www.brendangregg.com/flamegraphs.html

https://github.com/brendangregg/FlameGraph

页错误

https://yq.aliyun.com/articles/55820

http://cwndmiao.github.io/programming%20tools/2013/11/26/Dwarf/



Tags:perf   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
大家好,我是晓飞影!一个数码爱好者,也喜欢在众多平行领域探究摸索,让生活多一点乐趣。家用宽带测速我喜欢用 speedtest,界面简洁,准确快速,不过这个是测互联网的速度,如果家里的设备...【详细内容】
2021-10-21  Tags: perf  点击:(43)  评论:(0)  加入收藏
iperf是常用的网络吞吐量测试工具,用于通过测量服务器可以处理的最大网络吞吐量来诊断网络速度问题。它在遇到网络速度问题时特别有用,可以测TCP和UDP流量,现在很多网络资料都...【详细内容】
2021-08-24  Tags: perf  点击:(100)  评论:(0)  加入收藏
Dns 按钮显示域名服务器,然后单击DNS压力测试工具--DNSperf1、dnsperf简介DNSPerf(DNS Performance)来自Prospect One公司,刚好最近研究 DNS 又想起这项服务。DNSPerf 从全世界...【详细内容】
2020-05-07  Tags: perf  点击:(694)  评论:(0)  加入收藏
一、前言1、使用google开发的google-perftools优化nginx的内存分配效率和速度,帮助在高并发的情况下控制内存的使用。2、TCMalloc在内存的分配上效率和速度要比malloc高得多...【详细内容】
2019-12-03  Tags: perf  点击:(113)  评论:(0)  加入收藏
iperf命令 是一个网络性能测试工具。iperf可以测试TCP和UDP带宽质量。iperf可以测量最大TCP带宽,具有多种参数和UDP特性。iperf可以报告带宽,延迟抖动和数据包丢失。利用iper...【详细内容】
2019-11-25  Tags: perf  点击:(105)  评论:(0)  加入收藏
作为服务器后台开发,不仅仅要写业务逻辑,后台意味着高并发,稳定性,当你写了很多逻辑,发现性能有问题的时候,也要学会性能分析,进行性能优化, 也许你会接触很多性能分析工具:valgrind,gperftools,gprof, oprofile, 有时间慢慢一...【详细内容】
2019-11-11  Tags: perf  点击:(904)  评论:(0)  加入收藏
此前工作中,笔者使用perf测过CPU的CPI[1],cache miss, 内存带宽等性能指标。另外,还移植过perf uncore[2]相关的补丁。这些让我很好奇:perf大概是怎么工作的? 带着这个问题,笔者谨希望把自己的一点经验分享出来。...【详细内容】
2019-09-20  Tags: perf  点击:(215)  评论:(0)  加入收藏
▌简易百科推荐
阿里云镜像源地址及安装网站地址https://developer.aliyun.com/mirror/centos?spm=a2c6h.13651102.0.0.3e221b111kK44P更新源之前把之前的国外的镜像先备份一下 切换到yumcd...【详细内容】
2021-12-27  干程序那些事    Tags:CentOS7镜像   点击:(1)  评论:(0)  加入收藏
前言在实现TCP长连接功能中,客户端断线重连是一个很常见的问题,当我们使用netty实现断线重连时,是否考虑过如下几个问题: 如何监听到客户端和服务端连接断开 ? 如何实现断线后重...【详细内容】
2021-12-24  程序猿阿嘴  CSDN  Tags:Netty   点击:(12)  评论:(0)  加入收藏
一. 配置yum源在目录 /etc/yum.repos.d/ 下新建文件 google-chrome.repovim /etc/yum.repos.d/google-chrome.repo按i进入编辑模式写入如下内容:[google-chrome]name=googl...【详细内容】
2021-12-23  有云转晴    Tags:chrome   点击:(7)  评论:(0)  加入收藏
一. HTTP gzip压缩,概述 request header中声明Accept-Encoding : gzip,告知服务器客户端接受gzip的数据 response body,同时加入以下header:Content-Encoding: gzip:表明bo...【详细内容】
2021-12-22  java乐园    Tags:gzip压缩   点击:(9)  评论:(0)  加入收藏
yum -y install gcc automake autoconf libtool makeadduser testpasswd testmkdir /tmp/exploitln -s /usr/bin/ping /tmp/exploit/targetexec 3< /tmp/exploit/targetls -...【详细内容】
2021-12-22  SofM    Tags:Centos7   点击:(7)  评论:(0)  加入收藏
Windows操作系统和Linux操作系统有何区别?Windows操作系统:需支付版权费用,(华为云已购买正版版权,在华为云购买云服务器的用户安装系统时无需额外付费),界面化的操作系统对用户使...【详细内容】
2021-12-21  卷毛琴姨    Tags:云服务器   点击:(6)  评论:(0)  加入收藏
参考资料:Hive3.1.2安装指南_厦大数据库实验室博客Hive学习(一) 安装 环境:CentOS 7 + Hadoop3.2 + Hive3.1 - 一个人、一座城 - 博客园1.安装hive1.1下载地址hive镜像路径 ht...【详细内容】
2021-12-20  zebra-08    Tags:Hive   点击:(9)  评论:(0)  加入收藏
以下是服务器安全加固的步骤,本文以腾讯云的CentOS7.7版本为例来介绍,如果你使用的是秘钥登录服务器1-5步骤可以跳过。1、设置复杂密码服务器设置大写、小写、特殊字符、数字...【详细内容】
2021-12-20  网安人    Tags:服务器   点击:(7)  评论:(0)  加入收藏
项目中,遇到了一个问题,就是PDF等文档不能够在线预览,预览时会报错。错误描述浏览器的console中,显示如下错误:nginx代理服务报Mixed Content: The page at ******** was loaded...【详细内容】
2021-12-17  mdong    Tags:Nginx   点击:(7)  评论:(0)  加入收藏
转自: https://kermsite.com/p/wt-ssh/由于格式问题,部分链接、表格可能会失效,若失效请访问原文密码登录 以及 通过密钥实现免密码登录Dec 15, 2021阅读时长: 6 分钟简介Windo...【详细内容】
2021-12-17  LaLiLi    Tags:SSH连接   点击:(16)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条