Perf使用详解

Perf 工具深度解析

Perf (Performance Counters for Linux)是 Linux 系统的性能分析工具,基于内核的 perf_event 子系统,通过硬件性能计数器(PMC)、软件事件和跟踪点(tracepoints)实现全方位性能监控。


一、工作原理与实现机制

1. 核心组件
组件 作用
硬件性能计数器 利用 CPU 的 PMU(Performance Monitoring Unit)统计指令周期、缓存命中/失效等事件。
软件事件 内核插桩统计上下文切换、缺页异常等软件行为(如 context-switches)。
跟踪点 静态内核探针(如 sched:sched_switch),记录特定代码路径的执行信息。
kprobes/uprobes 动态内核/用户空间探针,支持自定义函数级跟踪。
2. 数据采集流程
plaintext 复制代码
+----------------+       +-------------------+       +-----------------+
| 配置事件        | ----> | perf_event_open() | ----> | 内核事件子系统   |
| (cycles, cache |       | (系统调用)        |       | (PMU/软件计数器) |
| misses, etc.)   |       +-------------------+       +-----------------+
+----------------+                     |
                                        v
+------------------+     mmap()      +--------------+
| 用户空间工具      | <------------- | 环形缓冲区     |
| (perf record/stat)|                 | (存储样本)    |
+------------------+                 +--------------+
3. 关键机制
  • 环形缓冲区:采样数据通过无锁环形缓冲(避免系统调用开销)传递到用户空间。
  • 采样模式
    • 计数模式 :累计事件发生次数(perf stat)。
    • 中断采样 :事件达到阈值时触发中断,记录指令指针/IP(perf record)。
  • 符号解析 :通过 /proc/kallsyms 或 ELF 文件将地址映射为函数名。

二、命令大全与使用示例

1. 常用命令总结
命令 功能 常用选项
perf stat 统计事件发生的绝对次数 -e (指定事件), -p (PID), -a (全局)
perf record 采样并保存数据到 perf.data -g (调用栈), -F (采样频率), -o (输出文件)
perf report 解析 perf.data 生成报告 --stdio (文本报告), -n (显示样本数)
perf top 实时显示热点函数 -e (事件), -K (隐藏内核符号)
perf list 列出支持的事件 --details (显示事件详情)
perf script 导出采样数据为脚本格式 -i (输入文件), -F (自定义字段)
perf trace 类似 strace,跟踪系统调用 -p (PID), -e (过滤系统调用)
perf annotate 汇编代码级注解 --stdio (文本模式), -s (符号)
2. 详细示例

Perf 典型使用场景及命令详解

2.1 CPU 性能分析
场景 命令示例 说明
CPU 热点函数分析 perf top -e cycles -p <PID> 实时查看进程的热点函数
调用链分析 perf record -F 99 -g -p <PID> -o perf.data; perf report --stdio 记录调用栈并生成文本报告
多核负载均衡分析 perf stat -e sched:sched_migrate_task -a sleep 10 监控任务在 CPU 核间的迁移情况
IPC 指标分析 perf stat -e cycles,instructions -p <PID> -- sleep 5 计算指令/周期比 (IPC = instructions/cycles)

示例:CPU 瓶颈诊断

bash 复制代码
# 1. 查找 CPU 占用最高的进程
perf top

# 2. 对高负载进程 (PID 1234) 进行采样
perf record -F 997 -g -p 1234 -o cpu_hotspot.data -- sleep 30

# 3. 生成带调用栈的报告
perf report -i cpu_hotspot.data --stdio --no-children

输出片段

复制代码
# Overhead  Command  Shared Object     Symbol
# ........  .......  ................  ................................
#
    62.15%  nginx    nginx             [.] ngx_http_process_request
            |
            ---ngx_http_process_request
               |          
               |--45.32%-- ngx_http_core_content_phase
               |          ngx_http_proxy_handler
               |          |
               |          |--38.71%-- ngx_http_upstream_connect
               |          |          __connect

2.2 内存子系统分析
场景 命令示例 说明
缓存命中率分析 perf stat -e cache-references,cache-misses <command> 统计 L1/L2/L3 缓存效率
内存带宽分析 perf stat -e uncore_imc_0/cas_count_read/,uncore_imc_0/cas_count_write/ 监控 DDR 内存读写带宽 (需 Intel PMU)
缺页异常分析 perf stat -e page-faults,minor-faults,major-faults -p <PID> 区分次/主缺页异常

示例:内存敏感型应用优化

bash 复制代码
# 1. 检测缓存效率
perf stat -e \
  L1-dcache-load-misses,LLC-load-misses,dTLB-load-misses \
  ./memory_intensive_app

# 2. 输出结果
  35,421,632  L1-dcache-load-misses     #  12.45% of all L1-dcache hits  
   8,765,432  LLC-load-misses           #   3.21% of all LL-cache hits
   1,234,567  dTLB-load-misses          #   0.45% of all dTLB cache hits

2.3 I/O 性能分析
场景 命令示例 说明
块设备 I/O 延迟 perf record -e block:block_rq_issue,block:block_rq_complete -a 跟踪块设备请求生命周期
文件系统操作跟踪 perf record -e ext4:*,xfs:* -a 捕获特定文件系统事件
系统调用分析 perf trace -e 'read,write,openat' -p <PID> 监控文件相关系统调用

示例:磁盘 I/O 瓶颈诊断

bash 复制代码
# 1. 跟踪块设备事件
perf record -e block:block_rq_issue -e block:block_rq_complete -a

# 2. 生成延迟报告
perf script | awk '/block_rq_issue/{ts[$5]=$4}/block_rq_complete/{if(ts[$5])printf "%.2f ms\n", ($4-ts[$5])*1000}'

输出

复制代码
8.23 ms  # I/O 请求延迟
12.45 ms
5.67 ms

2.4 网络性能分析
场景 命令示例 说明
网络协议栈跟踪 perf record -e skb:kfree_skb -e net:net_dev_xmit -a 监控丢包和发送事件
TCP 函数跟踪 perf probe --add tcp_v4_connect; perf record -e probe:tcp_v4_connect 动态跟踪 TCP 连接建立
网络延迟分析 perf trace -e sendto,recvfrom -p <PID> -T 跟踪网络收发系统调用时间戳

示例:网络丢包分析

bash 复制代码
# 1. 创建丢包检测探针
sudo perf probe --add 'kfree_skb reason'

# 2. 记录丢包事件
sudo perf record -e probe:kfree_skb -aR -o net_drop.data

# 3. 分析丢包原因
sudo perf script -i net_drop.data | awk '{print $5}' | sort | uniq -c | sort -nr

输出

复制代码
 1423 TCP: Too many orphaned sockets
  890 NETDEV WATCHDOG: enp0s3 transmit timeout
  321 ICMP: Destination unreachable

2.5 锁与同步分析
场景 命令示例 说明
锁竞争分析 perf record -e lock:lock_acquire -e lock:lock_release -g -p <PID> 跟踪锁获取/释放事件
调度延迟分析 perf sched record -p <PID>; perf sched latency 分析任务调度延迟
中断分析 perf record -e irq:irq_handler_entry -e irq:irq_handler_exit -a 跟踪中断处理时间

示例:锁竞争诊断

bash 复制代码
# 1. 记录锁事件
perf record -e lock:lock_acquire -e lock:lock_release -g -p 5678 -o locks.data

# 2. 生成竞争报告
perf lock report -i locks.data --combine-locks --sort contended

输出

复制代码
                Name   acquired  contended   avg wait (ns)
----------------------------------------------------------
&sb->s_type->i_lock    14235      4231        15234
        &rq->lock      8765       2109         8765
       mm->page_table_lock 6543     987          5432

2.6 火焰图生成
bash 复制代码
perf record -F 99 -a -g -- sleep 30
perf script > out.perf
./FlameGraph/stackcollapse-perf.pl out.perf > out.folded
./FlameGraph/flamegraph.pl out.folded > flame.svg
2.7 Perf 工作流程图

CPU 瓶颈 内存瓶颈 I/O 瓶颈 网络问题 锁竞争 确定分析目标 性能问题类型 perf record/top perf stat -e cache perf trace -e block perf probe + net events perf lock 生成火焰图/报告 缓存命中率报告 I/O 延迟直方图 丢包原因统计 锁竞争分析 优化热点函数 调整数据布局 优化 I/O 模式 调整网络参数 减少锁粒度


2.8 高级技巧
  1. PEBS 精确采样

    bash 复制代码
    perf record -e cycles:pp -c 1000000 -p <PID>  # 每100万周期采样一次
  2. 事件分组统计

    bash 复制代码
    perf stat -e '{cycles,instructions,branch-misses}' -r 5 ./program
  3. 时间戳跟踪

    bash 复制代码
    perf record -e sched:sched_switch -T -a -- sleep 10
    perf script --ns
  4. 跨进程跟踪

    bash 复制代码
    perf record -e 'sched:sched_wakeup,sched:sched_switch' -a
  5. 用户空间探针

    bash 复制代码
    perf probe -x /path/to/bin 'func_name'
    perf record -e probe_bin:func_name -a

三、Perf 使用流程图

计数模式 采样模式 实时模式 动态跟踪 启动分析 选择模式 perf stat perf record 保存到 perf.data perf report/report 生成文本/图形报告 perf top perf probe + record perf script 分析日志 优化代码/系统


四、高级技巧

  1. 事件修饰符

    • u:仅用户空间,如 perf stat -e cycles:u
    • k:仅内核空间
  2. 精确采样

    bash 复制代码
    perf record -e cycles:pp -p 1234  # 使用 PEBS 精确采样
  3. 多事件分析

    bash 复制代码
    perf stat -e cycles,instructions,cache-references,cache-misses ls

五、注意事项

  • 权限要求 :部分事件需要 CAP_PERFMONroot 权限。
  • 符号表 :用户程序需编译时添加 -g 选项(保留调试符号)。
  • 内核版本 :不同内核版本支持事件可能不同(perf list 查看)。

通过灵活组合命令,Perf 可定位 CPU 瓶颈、内存延迟、I/O 问题等,是 Linux 性能调优的核心工具。

相关推荐
小浣浣21 分钟前
为何她总在关键时“失联”?—— 解密 TCP 连接异常中断
网络·网络协议·tcp/ip
曳渔44 分钟前
UDP/TCP套接字编程简单实战指南
java·开发语言·网络·网络协议·tcp/ip·udp
楼田莉子1 小时前
C++算法题目分享:二叉搜索树相关的习题
数据结构·c++·学习·算法·leetcode·面试
Wgllss1 小时前
雷电雨效果:Kotlin+Compose+协程+Flow 实现天气UI
android·架构·android jetpack
pusue_the_sun2 小时前
数据结构——栈和队列oj练习
c语言·数据结构·算法··队列
大锦终2 小时前
【算法】模拟专题
c++·算法
归辞...2 小时前
「iOS」————设计架构
ios·架构
Lovyk2 小时前
Ansible 核心功能进阶:自动化任务的灵活控制与管理
网络
bing.shao2 小时前
微服务容错与监控体系设计
微服务·云原生·架构
小米里的大麦2 小时前
022 基础 IO —— 文件
linux