perf学习总结

article/2025/9/26 13:20:20

本文梳理一下工作中对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输出解读


http://chatgpt.dhexx.cn/article/8dpmWHGe.shtml

相关文章

Perf的原理、编译以及使用

​1、背景 1.1 性能分析 系统级性能优化通常包括两个阶段&#xff1a;性能剖析&#xff08;performance profiling&#xff09;和代码优化。性能剖析的目标是寻找性能瓶颈&#xff0c;查找引发性能问题的原因及热点代码。代码优化的目标是针对具体性能问题而优化代码或编译选…

学会使用perf性能分析工具--这一篇就够了

在功能上&#xff0c;perf很强大&#xff0c;可以对众多的软硬件事件采样&#xff0c;还能采集出跟踪点&#xff08;trace points&#xff09;的信息&#xff08;比如系统调用、TCP/IP事件和文件系统操作。perf的代码和Linux内核代码放在一起&#xff0c;是内核级的工具。perf是…

perf的基本使用方法

目录 前言perf的基本使用方法perf listperf statperf topperf record/perf reportperf -eperf probeperf schedperf sched mapperf sched scriptperf sched replay perf lockperf kmemperf timechartperf script 参考文档 前言 声明&#xff1a;本文主要参考几位老师的博文&…

Linux常用命令——ldconfig命令

在线Linux命令查询工具 ldconfig 动态链接库管理命令 补充说明 ldconfig命令的用途主要是在默认搜寻目录/lib和/usr/lib以及动态库配置文件/etc/ld.so.conf内所列的目录下&#xff0c;搜索出可共享的动态链接库&#xff08;格式如lib*.so*&#xff09;,进而创建出动态装入程…

[JavaScript] 理解 e.clientX,e.clientY e.pageX e.pageY e.offsetX e.offsetY

event.clientX、event.clientY 鼠标相对于浏览器窗口可视区域的X&#xff0c;Y坐标&#xff08;窗口坐标&#xff09;&#xff0c;可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性 event.pageX、event.pageY 类似于event.clientX、event.clientY&#xff…

clientX,clientY,offsetY,offsetX,screenX,screenY区分

在js中clientX&#xff0c;clientY&#xff0c;offsetX&#xff0c;offsetY&#xff0c;screenX&#xff0c;screenY都是鼠标事件的几个对象&#xff1a; 如下图可知&#xff1a; clientX&#xff1a;在鼠标事件发生时&#xff0c;鼠标相对于浏览器位置的X轴位置&#xff08;…

pageX/pageY、clientX/clientY、screenX/screenY的区别

在触发鼠标事件的时候会传一个event参数&#xff0c;在这个参数中我们可以获得pageX/pageY、clientX/clientY、screenX/screenY&#xff0c;但是这几个属性有啥区别呢&#xff1f;看下图 screenX/screenY&#xff1a;其实就是你的鼠标指针距离你电脑屏幕左侧边缘和上侧边缘的距…

event事件坐标详解(clientx, offsetx, screenX等)

鼠标事件&#xff08;ee||window.event&#xff09; event.clientX、event.clientY (相对浏览器窗口) //鼠标相对于浏览器窗口可视区域的X&#xff0c;Y坐标&#xff08;窗口坐标&#xff09;&#xff0c;可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性…

JS 中clientX clientY offsetX offsetY 等属性说明

JS中clientX clientY offsetX offsetY 等属性说明 示意图 event.clientX, event.clientY : 鼠标点击的位置距离 body 的大小event.screenX, event.screenY : 鼠标点击的位置距离 屏幕 的大小event.offsetX, event.offsetY 鼠标点击的位置距离 div盒子 的大小 没有滚动条的情…

clientX与offsetX、clientWidth与offsetWidth的区别

相关属性介绍 都要结合鼠标事件监听使用 1、client相关属性 获取鼠标位置 鼠标相对于视口的位置 e.clientX e.clientY &#xff08;e是鼠标对象&#xff09; 获取节点尺寸 节点.clientWidth; 节点.clientHeight;&#xff08;返回值为数值&#xff09; clientWidth cont…

图解事件坐标screenX、clientX、pageX, offsetX的区别

一、图解 如图所示&#xff0c;假设页面中灰色圆点是鼠标点击处&#xff0c;黄色区域是鼠标触发事件对象 二、概念 1、screenX 和screenY 参照点&#xff1a;电脑屏幕左上角screenX&#xff1a;鼠标点击位置相对于电脑屏幕左上角的水平偏移量screenY&#xff1a;鼠标点击位置…

clientX、pageX、screenX以及offsetX区别

clientX、pageX、clientX以及offsetX区别 client系列&#xff08;不包含滚动条&#xff09; clientX&#xff1a;鼠标相对于浏览器窗口可视区域x方向坐标 clientY&#xff1a;鼠标相对于浏览器窗口可视区域y方向坐标 page系列&#xff08;包含滚动条&#xff09; pageX&…

Client/Service

目录 客户--服务器方式 客户程序: 服务程序 TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户(client),而被动等待连接建立的应用进程叫做服务器(server)。 客户--服务器方式 客户(client)和服务器(server)都是指通信中所涉及的两个应用进程。客户-服务…

js鼠标事件 clientX、clientY、offsetX、offsetY、layerX、layerY、pageX、 pageY、screenX、screenY

MouseEvent的类别有以下&#xff1a; mousedown 鼠标按下mouseup 鼠标释放click 左键单击dblclick 左键双击mousemove 鼠标移动mouseover 鼠标经过mouseout 鼠标滑出mouseenter 鼠标进入mouseleave 鼠标离开contextmenu 右键菜单 注意&#xff1a; 执行顺序&#xff1a;mous…

图解offsetX、offsetY和clientX、clientY和pageX、pageY和screenX、screenY的区别

offsetX、offsetY: 鼠标相对于事件源元素的X,Y坐标。比如说&#xff0c;我给黄色的盒子定义一个点击事件&#xff0c;则这个offset的坐标原点就在这个黄色盒子的左上角 clientX、clientY: 鼠标相对于浏览器窗口可视区域的X&#xff0c;Y坐标&#xff08;窗口坐标&#xff09;&…

clientX, clientY | offsetX, offsetY | pageX, pageY的区别:

clientX, clientY | offsetX, offsetY | pageX, pageY的区别&#xff1a; ✍ clientX, clientY&#xff1a;指的是鼠标点击位置距离可视窗口的坐标&#xff1b; 图示&#xff1a;在不拉滚动条的情况下 在拉滚动条的情况下&#xff1a; 还是点击位置距离可视窗口左上角的距离 …

clientX和clientY

####需求&#xff1a; 做项目中遇到一个这样的需求&#xff0c;点击属性菜单节点&#xff0c;出现显示框&#xff0c;显示框的位置随着鼠标点击的位置距离而改变。 ###教程&#xff1a; clientX 事件属性 http://www.runoob.com/jsref/event-clientx.html clientY 事件属性 h…

pageX和clientX的区别

目录 定义&#xff1a; 代码求证 结论&#xff1a; 定义&#xff1a; e.page:返回鼠标相对于文档页面的左上角的坐标&#xff08;滚轮滑动时改变&#xff09; page的大小页面滚动部分大小距离窗口可视区距离的大小(距离整个文档左上角距离的大小) e.client:返回鼠标相对于浏…

HTML 页面中的位置:clientX、screenX、offsetX、pageX

事件中鼠标的 (x,y) 位置 clientX 鼠标相对于浏览器左上角x轴的坐标&#xff1b; 不随滚动条滚动而改变&#xff1b;clientY 鼠标相对于浏览器左上角y轴的坐标&#xff1b; 不随滚动条滚动而改变&#xff1b;pageX 鼠标相对于浏览器左上角x轴的坐标&#xff1b; 随滚动条滚动而…

JavaScript 中一些概念理解 :clientX、clientY、offsetX、offsetY、screenX、screenY

clientX&#xff1a; 设置或获取鼠标指针位置相对于窗口客户区域的 x 坐标&#xff0c;其中客户区域不包括窗口自身的控件和滚动条。 clientY&#xff1a; 设置或获取鼠标指针位置相对于窗口客户区域的 y 坐标&#xff0c;其中客户区域不包括窗口自身的控件和滚动条。 offset…