perf学习总结

2 篇文章 0 订阅
1 篇文章 0 订阅

本文梳理一下工作中对perf工具的使用,文章开始部分的概念和原理借用了网络上很多不错的文章(如有侵权欢迎联系),后面笔者争取展示一下在工作中使用perf来解决性能问题的实例。

perf概述

perf是Linux下的一款性能分析工具,能够进行函数级与指令级的热点查找。它由一个叫“Performance counters“的内核子系统实现,基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析,可用于性能瓶颈的查找与热点代码的定位。

perf原理

Perf通过系统调用sys_perf_event_open陷入到内核中,内核根据perf提供的信息在PMU(Performance Monitoring Unit)上初始化一个硬件性能计数器(PMC: Performance Monitoring Counter)。PMC随着指定硬件事件的发生而自动累加。在PMC 溢出时,PMU触发一个PMI(Performance Monitoring Interrupt)中断。内核在PMI 中断的处理函数中保存PMC的计数值,触发中断时的指令地址,当前时间戳以及当前进程的PID、TID、comm 等信息。我们把这些信息统称为一个采样(sample)。内核会将收集到的sample放入用于跟用户空间通信的Ring Buffer。用户空间里的perf分析程序采用mmap机制从ring buffer中读入采样,并对其解析。

perf支持两种模式:计算模式和采样模式。
后面解释perf stat使用的是计数模式,perf record使用的是采样模式。 

性能事件

在程序运行中发生的,可能影响到程序性能的软硬件事件,使用perf list命令可以显示当前软硬件环境下支持的所有事件,大致可以分为三种:
Hardware Event由PMU部件产生,在特定的条件下探测性能事件是否发生以及发生的次数。比如CPU周期、分支指令、TLB重填例外、Cache缺失等。Software Event是内核产生的事件,分布在各个功能模块中,统计和操作系统相关性能事件。比如系统调用次数、上下文切换次数、任务迁移次数、缺页例外次数等。Tracepoint Event是内核中静态tracepoint所触发的事件,这些tracepoint用来判断程序运行期间内核的行为细节,比如slab分配器的分配次数等。基于ftrace框架实现,内核中的所有tracepoint都可以作为perf都性能事件cat /sys/kernel/debug/tracing/available_events,可查看当前系统的所有tracepoint分成了几大类:
ext4 文件系统的tracepoint events,如果是其它文件系统,比如XFS,也有对应的tracepoint event;
jbd2 文件日志的tracepoint events;
skb 内存的tracepoint events;
net,napi,sock,udp:网络的tracepoint events;
scsi, block, writeback 磁盘IO
kmem 内存
sched 调度
syscalls 系统调用

性能事件的属性

硬件性能事件由处理器中的PMU提供支持。由于现代处理器的主频非常高,再加上深度流水线机制,从性能事件被触发,到处理器响应PMI中断,流水线上可能已处理过数百条指令。那么PMI中断采到的指令地址就不再是触发性能事件的那条指令的地址了,而且可能具有非常严重的偏差。为了解决这个问题,Intel处理器通过PEBS机制实现了高精度事件采样。PEBS通过硬件在计数器溢出时将处理器现场直接保存到内存(而不是在响应中断时才保存寄存器现场),从而使得perf能够采到真正触发性能事件的那条指令的地址,提高了采样精度。在默认条件下,perf不使用PEBS机制。用户如果想要使用高精度采样,需要在指定性能事件时,在事件名后添加后缀”:p”或”:pp”。Perf在采样精度上定义了4个级别,如下表所示。

级别描述
0 无精度保证
1 采样指令与触发性能事件的指令之间的偏差为常数(:p)
2 需要尽量保证采样指令与触发性能事件的指令之间的偏差为0(:pp)
3 保证采样指令与触发性能事件的指令之间的偏差必须为0(:ppp)
性能事件的精度级别目前的X86处理器,包括Intel处理器与AMD处理器均仅能实现前 3 个精度级别。
除了精度级别以外,性能事件还具有其它几个属性,均可以通过”event:X”的方式予以指定。

标志属性
u 仅统计用户空间程序触发的性能事件
k 仅统计内核触发的性能事件
h 仅统计Hypervisor触发的性能事件
G 在KVM虚拟机中,仅统计Guest系统触发的性能事件
H 仅统计 Host 系统触发的性能事件
p 精度级别

perf常用事件

在理解perf常用命令的用法后,进一步需要理解的地方就是perf性能调优用的常用事件。理解这些事件更多的是要理解计算机原理、操作系统原理、程序运行机制等一些底层概念才能做到如臂使指。cpu-clocktask-clockcyclesbranch‐misses 分支预测失效的事件
CPU-migrations cpu迁移事件
page-faults 缺页事件

perf常用命令

perf共22种子命令,常用的是以下5种:

perf list:查看当前软硬件环境支持的性能事件
perf stat:分析指定程序的性能概况
perf top:实时显示系统/进程的性能统计信息
perf record:记录一段时间内系统/进程的性能事件
perf report:读取perf record生成的perf.data文件,并显示分析数据

perf stat

默认事件简介:

  1. task-clock:任务真正占用的处理器时间,单位为ms。CPUs utilized = task-clock / time elapsed,CPU的占用率,值高,说明程序的多数时间花费在CPU计算上而非IO。
  2. context-switches:上下文的切换次数。
    CPU-migrations:处理器迁移次数。Linux为了维持多个处理器的负载均衡,在特定条件下会将某个任务从一个CPU迁移到另一个CPU。
  3. page-faults:缺页异常的次数。当应用程序请求的页面尚未建立、请求的页面不在内存中,或者请求的页面虽然在内存中,但物理地址和虚拟地址的映射关系尚未建立时,都会触发一次缺页异常。另外TLB不命中,页面访问权限不匹配等情况也会触发缺页异常。
  4. cycles:消耗的处理器周期数。
  5. instructions:执行了多少条指令。IPC为平均每个cpu cycle执行了多少条。
  6. branches:遇到的分支指令数。
  7. branch-misses:预测错误的分支指令数。

perf stat参数

-e <event>:指定性能事件(可以是多个,用,分隔列表)
-p <pid>:指定待分析进程的 pid(可以是多个,用,分隔列表)
-t <tid>;:指定待分析线程的 tid(可以是多个,用,分隔列表)
-a:从所有 CPU 收集系统数据
-d:打印更详细的信息,可重复 3 次
    -d:L1 和 LLC data cache
    -d -d:dTLB 和 iTLB events
    -d -d -d:增加 prefetch events
-r <n>;:重复运行命令 n 次,打印平均值。n 设为 0 时无限循环打印
-c <cpu-list>:只统计指定 CPU 列表的数据,如:0,1,3或1-2
-A:与-a选项联用,不要将 CPU 计数聚合
-I <N msecs>:每隔 N 毫秒打印一次计数器的变化,N 最小值为 100 毫秒

perf top

常用命令行参数:
-e <event>:指明要分析的性能事件。
-p <pid>:仅分析目标进程及其创建的线程。
-k <path>:带符号表的内核映像所在的路径。
-K:不显示属于内核或模块的符号。
-U:不显示属于用户态程序的符号。
-d <n>:界面的刷新周期,默认为2s。
-g:得到函数的调用关系图

perf record

收集一段时间内的性能事件到文件 perf.data,随后需要用perf report命令分析。

-e <event>:指定性能事件(可以是多个,用,分隔列表)
-p <pid>:指定待分析进程的 pid(可以是多个,用,分隔列表)
-t <tid>:指定待分析线程的 tid(可以是多个,用,分隔列表)
-u <uid>:指定收集的用户数据,uid为名称或数字
-a:从所有 CPU 收集系统数据
-g:开启 call-graph (stack chain/backtrace) 记录
-C <cpu-list>:只统计指定 CPU 列表的数据,如:0,1,3或1-2
-r <RT priority>:perf 程序以SCHED_FIFO实时优先级RT priority运行这里填入的数值越大,进程优先级越高(即 nice 值越小)
-c <count>: 事件每发生 count 次采一次样
-F <n>:每秒采样 n 次
-o <output.data>:指定输出文件output.data,默认输出到perf.data

perf应用案例

对于一种工具,首先要知道它能用来做什么的,然后要知道怎么去用它。像perf这样功能强大的性能分析工具,聪明人可能找出问题点,一条命令即可找到程序热点;但对于不那么聪明但人(我),还是需要想办法形成一套方法但,或者说是形成一种套路,最好能做到有条有理,循序渐进,慢慢逼近问题的真相。分析和调查Linux上的各种性能问题,需要我们对Linux内核有比较多的了解,不然恐怕是无从下手的。

perf stat获取基准性能

分析的第一步是要获取一个基准性能,后面所有的优化都和这个基准性能做对比。不要忘记编译器的优化选项,很多时候使用编译器的优化就足以解决性能问题。cpu-clock事件正是此步需要的,它以毫秒为单位显示cpu时钟事件的数量以及执行时间。(It displays the number of cpu-clock events in milliseconds and the elapsed execution time. These times are the baseline for future comparisons.)

利用perf性能调优时需要回答3个问题:

  1. 程序的哪一部分耗用了最多的时间?(Which parts of the program take the most execution time?)程序占用时间最多的部分称为“热点”。对热点进行优化分析是最有价值的,有可能很小的改动,得到意想不到的效果。
  2. 软/硬件性能事件的数量就代表需要实际修正的问题吗?(Do the number of software or hardware events indicate an actual performance issue to be fixed?)要回答这个问题,我们需要对程序中的算法和数据结构有一定的了解或直觉。了解程序的类型,是cpu密集性、memory密集性、io密集性,然后在针对热点位置具体分析。
  3. 如何修正这些性能问题?(How can we fix the performance issue?)我们需要研究程序的算法和数据结构,找到其中不合理的地方,修改代码,然后观察效果。性能调优是一项艰巨的实验工作,如果修改后的程序运行速度低于基准速度,请不要感到惊讶。如果一个假设失败,则尝试另一个。继续尝试!

参考资料

Linux kernel profiling with perf
PERF tutorial: Finding execution hot spots
Perf -- Linux下的系统性能调优工具,第 1 部分perf + 火焰图分析程序性能
Perf介绍
在Linux下做性能分析3:perf
perf 性能分析实例——使用perf优化cache利用率Perf
深度解析perf
perf stat输出解读

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值