Perf Linux性能事件(性能计数)器 与 Flame Graph

news/2025/2/24 7:12:18/文章来源:https://www.cnblogs.com/cilinmengye/p/18566505

image

from ふぃーる 冬コミ2日目西ふ15

Perf 性能采样和计数原理

首先要清楚perf是一个面向事件的可观察性工具
image

from jyy

perf在中断来临时,获取OS在中断之前所记录的关键性能指标
image

Perf Stat (性能计数)

stat (statistics) 有统计,计数,获取信息等含义

perf stat <command>对程序运行时所发生的性能事件进行统计:
image

from jyy

not supported 是因为jyy老师用的虚拟机上一些功能不支持

Perf Record (性能采样)及其可视化

采样

perf record -o perfData/perf.data -e cycles -g -F 99 ./a
perf report -i perfData/perf.data
  • -o 指定搜集的数据保存地址
  • -e cycles -e指定采集的事件,cycles表示CPU时钟周期数
  • -g 表示开启调用栈采样,便于分析程序中函数调用关系
  • -F 表示指定采集频率(HZ 每秒采样次数),这里表示每秒采样 99 次
  • perf report中的-i 指定查看采集数据的地址

采集频率的设定会影响性能,不能太大或太小:

Balancing considerations that include sampling overhead, profile size, and application variation, a typical CPU profile might be collected in the following way: stack traces are sampled at a rate of 99 times per second (not 100, to avoid lock-step sampling)

99次是一种常见的使用频率,但是为何频率设置为100会出现所谓的lock-step sampling呢?


Lock-step sampling 指的是当采样事件与系统或程序的周期性行为锁定(lock in)时,采样可能总是在特定的执行状态或代码路径中触发,导致采样结果不能反映程序的全局行为。这会引入以下问题:

  • 偏差(Bias):采样可能总是在某些特定的函数、线程或代码路径上触发,遗漏其他关键路径。
  • 不准确:分析结果可能错误地将某些函数误判为性能瓶颈,或者完全忽视实际的热点。

导致可能有:

  • (a) 系统周期性行为的同步
    现代计算机系统中的许多事件是周期性发生的,例如:

    • CPU 时钟信号的周期(Clock Cycle)。
    • 定时中断的触发频率(例如,操作系统调度器的时间片通常是 10ms,即 100Hz)。
    • 硬件计数器的刷新频率。
      如果采样频率(100Hz)与这些周期性事件的频率相同或成整数倍关系(同步),采样点就会总是落在这些事件的同一个状态上。例如:
    • 每次采样可能总是捕获到某些特定线程正在运行,而忽略了其他线程。
    • 如果某个函数在每个周期开始时被频繁调用,采样可能总是在捕获它,而忽略其他部分。
  • (b) 系统时间片的默认设置
    许多操作系统的任务调度器时间片默认是 10ms(100Hz)。如果采样频率也设为 100Hz,就会导致采样事件总是发生在时间片的开始或结束时。这种情况可能导致:

    • 采样总是在线程切换之前或之后触发,而无法反映线程运行中的真实状态。
    • 某些短时间运行的函数可能被完全忽略,因为它们总是在采样事件之间执行。
  • (c) 代码自身的周期性
    某些代码可能具有周期性行为,例如:

    • 循环内的操作可能具有固定执行时间。
    • 网络或 IO 轮询任务每隔固定时间运行一次。

更加具体的以数学计算表示:

image
image

栈帧和符号

参考巨佬写的博客:The Return of the Frame Pointers

总得来说就是在查看report和火焰图时符号出现了unknow
image

符号是通过栈帧得到的,栈帧是什么?

在 x86-64 架构中,%RBP(Base Pointer) 和 %RIP(Instruction Pointer) 是两个关键寄存器,用于标识栈帧信息和程序的执行位置。同时还有%rsp记录当前栈顶。

CPU 寄存器 %rbp 用作堆栈帧(也称为“帧指针”)的“基指针”。

image

(a)Stack Frame with Base Pointer (x86-64 ABI)

image

(b) Frame Pointer-based Stack Walking -- All from Brendan's site

通过 Stack-Walking(栈遍历),可以获取每个栈帧的函数调用关系、调用地址(程序计数器 PC),以及与函数调用相关的其他元信息。具体过程如下:

  1. 首先由(b)图可知,我们可以通过%rip得到当前正在运行指令的地址,只要能够知道指令的地址,就能够有方法知道这条指令是在那个函数下的,就可以知道函数名等元信息

  2. 然后(a)图可知可以通过当前%rbp的值得到父函数的栈帧地址,即上一栈帧的地址。
    通过对%rbp做位移(即8(%rbp))可以知道父函数的返回后要执行指令的地址,从而得到父函数的元信息。

  3. 利用previous %rbp value进行跳转,跳转到父函数的栈帧上,从而可以得到祖父的栈帧信息和返回后要执行指令的地址信息,从而得到祖父函数的元信息。

  4. 不断如此,可以得到整个函数调用链。

遇到的困难

在上述巨佬写的博客中也描述了遇到的困难:

the flame graph looks ok at first glance. But there are 15% of samples on the left, above "[unknown]", that are in the wrong place and missing frames.

The problem is that this system has a default libc that has been compiled without frame pointers, so any stack walking stops at the libc layer, producing a partial stack that's missing the application frames.

libc 是 C 标准库 (Standard C Library) 的实现,是所有 C 程序运行时的基础库,提供了许多核心功能。

系统中默认的 libc(标准 C 库)没有启用 frame pointers(帧指针) 的编译选项,导致在使用工具进行 栈回溯(stack walking) 时只能获取部分调用栈信息。这种情况下,调用栈在到达 libc 层时中断,无法追溯到应用程序层的调用栈信息。

有些编译器(如 GCC 和 Clang)or 系统默认会启用优化选项(如 -fomit-frame-pointer),省略帧指针 以释放寄存器资源,提高性能。

最佳实践

参考资料

  • The Flame Graph This visualization of software execution is a new necessity for performance profiling and debugging -- 详细介绍火焰图在性能分析上的运用
  • Java Performance Analysis on Linux with Flame Graphs -- 用火焰图分析Java性能

Reference

  • Brendan's site: perf Examples -- 巨佬的博客
  • The Flame Graph -- 巨佬的文章,讲解火焰图的最佳实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/840621.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技术债正在悄悄拖垮你的团队!

0 前言 软件开发的核心在于应对变化。在软件的生命周期中,目标是能够在合理的时间内实施必要的更改。不管这些更改是技术性的,比如紧急安全升级,还是业务需求所驱动的,比如开发新功能以在目标市场中更具竞争力——能否快速应对变化是成败的关键。 是什么让我们慢下来?通常…

HCIA-06 IP路由基础

介绍了路由的基本概念,路由条目三种生成方式:直连路由、静态路由(缺省路由)、动态路由,路由器的基本工作原理、路由表的具体内容。路由器选择最佳路由的方法:先比较匹配的掩码长度、(如果掩码长度相同)再比较优先级、(如果优先级相同)再比较度量值。路由转发选择的路…

学习笔记(四十四):自定义组件@LocalBuilder装饰器

概述: 当开发者使用@Builder做引用数据传递时,会考虑组件的父子关系,使用了bind(this)之后,组件的父子关系和状态管理的父子关系并不一致。 为了解决组件的父子关系和状态管理的父子关系保持一致的问题,引入@LocalBuilder装饰器。 @LocalBuilder拥有和局部@Builder相同的功…

推荐5款程序员必备的画图工具,效率提升利器!

ProcessOn ProcessOn是一款专业强大在线作图工具,提供AI生成思维导图流程图,支持思维导图、流程图、组织结构图、网络拓扑图、鱼骨图、UML图等多种图形。同时可实现人与人之间的实时协作和共享,提升团队工作效率。在线访问地址:https://www.processon.com丰富的图形素材库:…

定时器JS深入理解解读

set&clear interval&timeout 相信不论是老油条还是新手小白,你早就听过或者用过setInterval和setTimeout这俩哥们儿和他们的死敌clearInterval和clearTimeout了吧,作为项目里的“老面孔”和面试高频考点,今天GJ504b就带大家深入解读这四大活宝😀setInterval/setT…

not in 和 not exists 比较和用法

尽量不要使用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)。查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。 NOT IN 查询返回空结果:…

Flash动画综合设计并发布、嵌入到网页

【作业要求】 自己选定主题,创意制作Flash动画,并与网页进行集成 【实验环境】 l 所需硬件环境为微机; l 所需软件环境为VS code 【创意内容】 因为我比较爱国,所以我选定的主题都是关于国旗的【关键步骤】 1、选好想要做的内容,找到一些视频; 2、查找关于任如何在浏览器…

洛谷P11290 【MX-S6-T2】「KDOI-11」飞船

Problem本题开启Special Judge,无需考虑精度问题Solve 一开始想到这个用DP写,但是不知道怎么定义 去"提交记录"旁边的神秘按钮得知速度可以作为第二维,且类似于背包 那么我们就可以按照背包列出定义 前i个加油站,花费时间j...... 但是这里是求最小花费,所以我们…

Analogue Pocket 软硬件实验预告

如题,还在测试中,预计会在今年内发布。

.NET云原生应用实践(六):多租户初步

本章目标多租户简介 实现public租户下的用户数据隔离出于开发进度考虑,本章暂不会完全实现多租户的整套体系,而是会实现其中的一小部分:基于默认public租户的数据隔离,并在本章节中会讨论多租户的实现框架结构。在后续的系列文章章节中,我们会完成多租户的实现。多租户(M…

【MX-S7】梦熊 NOIP 2024 模拟赛 3 SMOI Round 2

hdk俩签到俩不可做是吧。Rank【MX-S7-T1】「SMOI-R2」Happy Card 签到题一号,以为撑死评个黄但没想到那么多人不会打扑克。 考虑炸弹也是三带一,出三带一肯定更优秀。 考虑将所有牌变为若干个三张和剩余的,那么三张先带单张,再将对子拆开带。那么现在就有以下几种情况:单张…