Perf抓取CPU热点函数

背景:

为了查询应用运行卡顿的原因,使用perf工具查找哪几个函数占用了较多的CPU资源,然后优化占用CPU资源最多的几个函数。

Perf工具简介

Perf是Linux内核提供的性能分析工具,能够监控CPU性能计数器、跟踪内核和用户态事件,帮助定位热点函数、缓存命中率等问题。它支持多种分析模式,如采样(sampling)、统计(counting)和追踪(tracing)。


安装Perf工具

在大多数Linux发行版中,Perf可通过包管理器安装:

  • Debian/Ubuntu:
    sudo apt install linux-tools-common linux-tools-$(uname -r)
    

  • RHEL/CentOS:
    sudo yum install perf
    

如果遇到版本兼容性问题,需确保内核头文件与当前运行的内核版本一致。


基本使用流程

1. 采样CPU事件

通过perf record采集CPU执行样本,默认监控cycles(CPU时钟周期)事件:

sudo perf record -F 99 -g -p <PID>  # -F 99表示每秒采样99次,-g启用调用栈,-p指定进程ID
sudo perf record -F 99 -g -a        # 监控所有CPU

运行结束后生成perf.data文件。

2. 生成分析报告

使用perf report解析采样数据:

sudo perf report -n --stdio         # 文本模式查看
sudo perf report -g                 # 图形化交互模式

报告会显示热点函数及其调用栈,按CPU占用百分比排序。

3. 统计事件计数

直接统计特定事件的发生次数(不生成详细样本):

sudo perf stat -e cycles,instructions,cache-misses -p <PID>


高级功能

火焰图生成
  1. 使用perf script导出采样数据:
    sudo perf script > out.perf
    

  2. 通过FlameGraph工具生成SVG火焰图:
    git clone https://github.com/brendangregg/FlameGraph
    ./FlameGraph/stackcollapse-perf.pl out.perf | ./FlameGraph/flamegraph.pl > flame.svg
    

    火焰图直观展示函数调用栈宽度与CPU占用比例。
追踪特定函数

监控内核或用户态函数的调用:

sudo perf probe --add 'schedule'          # 添加内核函数追踪点
sudo perf trace -e probe:schedule -p <PID>  # 追踪调用

硬件事件监控

Perf支持多种硬件性能计数器(PMC):

sudo perf record -e branch-misses,LLC-load-misses -a  # 监控分支预测失败、LLC未命中


常见问题

符号表缺失

若报告中函数名显示为十六进制地址,需确保调试符号已安装:

  • 对于应用程序:编译时添加-g选项。
  • 对于内核:安装dbgsym包(Debian)或debuginfo包(RHEL)。
权限问题

部分性能事件需要CAP_PERFMONroot权限,可通过以下命令临时授权:

sudo sysctl kernel.perf_event_paranoid=-1

多线程分析

结合-t选项监控特定线程:

sudo perf record -t <TID> -g -e cycles


示例输出解读

perf report的典型输出片段:

60.12%  program  libc.so.6    [.] malloc
        |
        --- malloc
           |          
            --50.2%-- foo
                      bar

表示malloc占用了60.12%的CPU时间,其中50.2%由foo->bar调用路径触发。


注意事项

  • 采样频率过高(如-F 1000)可能导致显著性能开销。
  • 内核版本差异可能导致部分功能不可用(如eBPF集成)。
  • 虚拟机环境可能限制硬件性能计数器的访问。

通过合理配置事件和采样频率,Perf能够高效定位CPU热点,为性能优化提供数据支撑。

嵌入式工作中需要注意的是,如果终端控制台敲perf命令显示没有这个命令,那么需要自己拉源码编译然后下载到机器中,同时也需要修改内核配置,make kernel_menuconfig->Enable performance events and counters,这是因为 perf 依赖于内核的 perf_events 子系统来采集性能数据,如果内核没有编译支持这个功能,perf 就会报错。

内核未支持,敲perf会报类似的错误:

perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error 38 (Function not implemented)
...
No CONFIG_PERF_EVENTS=y kernel support configured?

最后总结下常见的perf命令:

perf stat

perf stat用于统计程序运行时的性能事件,如CPU周期、缓存命中率等。示例:

perf stat -e cycles,instructions,cache-misses ./your_program

perf record

perf record用于记录程序运行时的性能数据,生成perf.data文件。示例:

perf record -g ./your_program

perf report

perf report用于分析perf record生成的数据文件。示例:

perf report -n --stdio

perf top

perf top实时显示系统或进程的性能事件,类似于top命令。示例:

perf top -e cycles

perf list

perf list列出当前系统支持的所有性能事件。示例:

perf list

perf annotate

perf annotate对特定函数进行代码级性能分析。示例:

perf annotate -s function_name

perf script

perf script将perf.data转换为可读文本或其他格式。示例:

perf script -F comm,pid,time,event

perf trace

perf trace跟踪系统调用和信号。示例:

perf trace -e nanosleep ./your_program

perf probe

perf probe动态添加跟踪点。示例:

perf probe --add 'schedule'

perf mem

perf mem分析内存访问性能。示例:

perf mem record ./your_program

<think>嗯,用户现在问的是关于如何使用perf工具抓取内核调用栈以及制作火焰图。我需要先回忆一下perf的基本用法和火焰图的制作步骤。首先,perfLinux内核自带的性能分析工具,可以收集各种性能数据,比如CPU的调用栈。火焰图则是一种可视化工具,能够直观展示调用栈的分布情况,帮助定位性能瓶颈。 用户之前已经询问过alarm的相关概念,现在转向性能分析工具,可能是在实际工作中遇到了性能问题,或者正在学习系统调优。考虑到用户可能是开发人员或者运维工程师,需要详细但清晰的步骤说明。他们可能需要从安装perf开始,到数据收集、生成火焰图的整个流程。 首先,我应该确认用户的操作系统环境,但可能用户没有说明,所以需要给出通用的步骤,比如安装perf工具,可能需要安装linux-tools或者相关包。然后,使用perf record命令记录调用栈,这里要提到常用的选项,比如-g(记录调用栈)、-F(采样频率)、-p(指定进程)等。接着,使用perf script将数据转换为可读格式,再通过FlameGraph脚本生成火焰图。 需要注意的是,用户可能对某些步骤不熟悉,比如如何获取FlameGraph的脚本库,是否需要克隆GitHub仓库。此外,权限问题也是常见的,比如运行perf可能需要sudo权限,或者调整内核参数如perf_event_paranoid。这些都是需要提及的。 另外,火焰图的解读方法也很重要。用户可能生成了火焰图,但不知道如何分析,所以需要简单说明如何查看火焰图,比如宽度代表资源占用,层级代表调用栈深度,以及如何识别热点函数。 可能用户遇到的困难包括采样频率设置不当导致数据不准确,或者生成火焰图时脚本路径错误。需要提醒常见问题及解决方法,比如权限问题、依赖安装等。此外,是否支持用户空间和内核空间的调用栈同时记录,这也是perf的优势之一,可以一并说明。 最后,总结步骤,确保用户能按部就班地操作,同时提供参考链接,方便进一步学习。还要保持回答的结构清晰,分步骤说明,使用代码块展示命令,这样用户容易复制和执行。</think>以下是使用 **`perf` 工具抓取内核调用栈并生成火焰图**的完整流程,适用于 Linux 系统性能分析: --- ### **1. 工具准备** #### (1) 安装 `perf` ```bash # Ubuntu/Debian sudo apt-get install linux-tools-common linux-tools-generic # CentOS/RHEL sudo yum install perf # 验证安装 perf --version ``` #### (2) 获取火焰图生成脚本 ```bash git clone https://github.com/brendangregg/FlameGraph.git cd FlameGraph # 后续步骤均在此目录下操作 ``` --- ### **2. 抓取调用栈数据** #### (1) 使用 `perf record` 采样 ```bash # 全局采样(所有进程) sudo perf record -F 99 -a -g -- sleep 60 # 采样 60 秒,频率 99Hz # 指定进程采样(PID=1234) sudo perf record -F 99 -p 1234 -g -- sleep 60 ``` - **参数说明**: - `-F 99`:采样频率(通常 99Hz 足够,避免过高影响性能)。 - `-a`:监控所有 CPU。 - `-g`:记录调用栈(即 `--call-graph`)。 - `-- sleep 60`:采样持续时间(单位:秒)。 #### (2) 生成原始数据文件 ```bash sudo perf script > perf.script # 将二进制数据转换为可读文本 ``` --- ### **3. 生成火焰图** #### (1) 处理数据并生成 SVG ```bash # 提取调用栈信息 ./stackcollapse-perf.pl perf.script > perf.folded # 生成火焰图 SVG ./flamegraph.pl perf.folded > flamegraph.svg ``` #### (2) 查看火焰图 ```bash xdg-open flamegraph.svg # 在浏览器中打开 ``` --- ### **4. 火焰图解读** - **横轴宽度**:表示函数在采样中出现的频率(即资源消耗占比)。 - **纵轴层级**:表示调用栈深度,顶层是正在运行的函数,下层是其调用者。 - **关键用途**: - 快速定位 CPU 热点(最宽的“塔”通常是性能瓶颈)。 - 分析内核与用户空间的调用链关系(如系统调用、锁竞争)。 --- ### **5. 高级用法** #### (1) 指定事件类型 ```bash # 监控特定事件(如缓存未命中、上下文切换) sudo perf record -e cache-misses -a -g -- sleep 10 ``` #### (2) 内核与用户空间分离 ```bash # 仅抓取内核调用栈 sudo perf record -a -g --kcore # 分离用户态和内核态火焰图 ./flamegraph.pl --color=java perf.folded > user.svg ./flamegraph.pl --color=hot perf.folded > kernel.svg ``` #### (3) 实时生成火焰图 ```bash # 一键式管道操作 sudo perf record -F 99 -a -g -- sleep 10; \ sudo perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > realtime.svg ``` --- ### **6. 常见问题** - **权限不足**:需 `sudo` 或调整 `/proc/sys/kernel/perf_event_paranoid` 值为 `-1`。 - **符号表缺失**:确保调试符号已安装(如 `linux-image-$(uname -r)-dbgsym`)。 - **火焰图空白**:检查采样时间是否太短或进程无 CPU 占用。 --- ### **参考工具链** - **perf**: Linux 内核内置性能分析工具。 - **FlameGraph**: Brendan Gregg 开源的火焰图生成脚本库。 - **Hotspot**: 图形化火焰图分析工具(基于 KDE)。 如果需要更具体的场景分析(如网络延迟、磁盘 I/O 火焰图),可进一步说明需求! 🔥
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值