首页 > 系统相关 >Perf Linux性能事件(性能计数)器 与 Flame Graph

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

时间:2024-11-24 23:35:40浏览次数:5  
标签:采样 调用 Perf Graph 性能 perf 地址 函数

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),省略帧指针 以释放寄存器资源,提高性能。

可视化

阮一峰 如何读懂火焰图?

火焰图样例

y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。

x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。 注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。

最佳实践

参考资料

Reference

标签:采样,调用,Perf,Graph,性能,perf,地址,函数
From: https://www.cnblogs.com/cilinmengye/p/18566505

相关文章

  • 驱动开发系列28 - Linux Graphics DRM代码分析 - 内部机制
    一:概述       本文介绍DRM的内部机制,这些特性与驱动程序作者和为现有驱动程序添加新功能的开发人员息息相关。       首先,我们将介绍一些典型的驱动程序初始化要求,如设置命令缓冲区,创建初始化输出配置和初始化核心服务。随后将更详细介绍核心内部结构,并提供......
  • 视野修炼-技术周刊第111期 | 读文件 API 性能对比
    欢迎来到第111期的【视野修炼-技术周刊】,下面是本期的精选内容简介......
  • 使用 GraphQL 查询
    Home / 发送请求 / 支持的API框架使用GraphQL查询除了REST,Postman还可以使用GraphQL(一种用于API的开源数据查询和操作语言)进行HTTP调用。您可以通过多种方式使用Postman编写和发送GraphQL查询:使用Postman对GraphQL的内置支持在请求正文中使用JS......
  • 项目代码性能优化
    性能优化之: 1. //减少了服务器请求次数 防抖:防止用户在短时间内操作多次(发送多次无意义请求) 验证码-通过使用input验证码/滑动验证/选图片等, 验证插件,实现先验证,再发送请求! 节流-让某个函数在指定时间内,只调用一次(肯定会和定时器搭配使用) 2.......
  • 当项目准备上线前,你有做过哪些性能优化吗?
    提供前端性能优化的常见策略和建议,供前端开发者参考:1.资源优化:代码压缩和混淆:减少文件大小,加快下载速度。可以使用工具如Webpack、Terser等。图片优化:使用合适的格式(WebP,AVIF),压缩图片,使用CDN,根据不同设备提供不同分辨率的图片(srcset和sizes属性)。字体优化:......
  • 有向无环图(DAG,Directed Acyclic Graph)算法
    大家好!今天我想给大家讲一个非常有趣的算法,叫做有向无环图(DAG,DirectedAcyclicGraph)算法。这个算法就像是在玩一个游戏,帮我们找到完成一系列任务的最佳顺序!什么是有向无环图?假设你喜欢做一些手工DIY,比如制作一个纸飞机。但你发现,做纸飞机需要先完成一些步骤,比如剪纸、折纸、......
  • 深度测评腾讯云 HAI 智算服务:高性能 AI 计算的新标杆
    本文一、引言二、产品功能深度解析2.1多样化的GPU配置选择2.2预配置开发环境示例:2.3实时性能监控三、核心技术特点与优势3.1云端弹性扩展3.2高性能计算架构四、实际测试与代码案例4.1NLP案例:使用BERT进行情感分类数据集:IMDb评论情感分析环境配置数据加载......
  • 高性能计算-探究循环分块优化(2-1)
    1.目标:分析循环分块优化技术,并分析cache命中情况假设每个cacheline可以存储b个数据元素。2.源代码分析for(inti=0;i<N;i++){ for(intj=0;j<M;j++) { A[i]+=B[j]; }}cachemiss分析:对A总访问次数为NM,每次访存加载一个cacheline可以加载b个元素,并且连续访问,......
  • FDTD仿真提高工作站性能
    性能测试问题:对lumericalfdtd软件,为什么在https://optics.ansys.com/hc/en-us/articles/4403780894355-FDTD-Performance-Benchmarks网页中,使用IntelXeonScalable8375C2.9GHz、64cores、256GBRAM的高性能工作站能够获得2106.1mNodes/s的求解器速度,我自己的高性能工作站为I......
  • 性能测试汇报面向公司决策层业务价值的呈现
    目录对业务价值的呈现对核心业务性能的提升核心业务性能基线性能测试结果汇报给公司决策层,针对业务价值趋向可以参考以下模板:1.明确目的与背景2.测试概述3.结果展示4.业务影响5.建议与行动计划6.互动环节小贴士:随着企业性能测试成熟度的提升,向上汇报是一个......