C++分析程序各模块耗时-perf火焰图

2024-04-07 22:04

本文主要是介绍C++分析程序各模块耗时-perf火焰图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C++分析程序各模块耗时-perf火焰图

  • 1. 简介
  • 2. 安装
  • 3. 测试示例
  • 4. 从火焰图可以获得的信息
  • 5. 生成火焰图常见问题

Reference:

  1. Perf Wiki
  2. 【性能】perf + 火焰图分析软件性能瓶颈
  3. 【火焰图🔥】Linux C/C++性能优化分析工具Perf使用教程

perf: Linux profiling with performance counters(带有性能计数器的Linux分析)

1. 简介

perf 是一个非常实用且深入的性能分析工具,适用于从底层硬件交互到上层应用程序逻辑的全方位性能剖析。

perf 工具的设计目的是为了帮助开发者和系统管理员分析应用程序以及内核本身的性能,寻找潜在的性能瓶颈,并据此进行针对性的优化。

2. 安装

sudo apt install linux-tools-common
// 下面步骤根据 Linux 内核来。比如查看 uname -a 得到内核版本,根据相应版本修改下面指令
sudo apt install linux-tools-5.15.0-101-generic

  • 查看 perf 版本

    perf --version

3. 测试示例

#include <stdio.h>
#include <stdlib.h>void long_test() {int i, j;for (i = 0; i < 1000000; i++) j = i;
}void foo2() {int i;for (i = 0; i < 10; i++) long_test();
}void foo1() {int i;for (i = 0; i < 100; i++) long_test();
}
int main(void) {foo1();foo2();
}
  1. 编译成二进制文件

    g++ -o test test.cpp

  2. 使用 perf 对系统 CPU 事件做采样
    采样60s,会生成一个perf.data文件(采样时间可自行设定):

    #方式一:对一个正在运行的进程,进行采样
    perf record -p PID[这里换成要检测的进程ID] -g – sleep 60
    #方式二:全新运行一个二进制文件main,进行采样
    sudo perf record -F 99 -g ./test – sleep 60

  3. 安装火焰图
    利用这个开源工具可以将报告生成可视化的svg图片,更容易查看对应的CPU开销时间和调用栈深度:

    git clone --depth 1 https://github.com/brendangregg/FlameGraph.git
    #安装perl
    yum install -y perl

  4. 生成火焰图
    生成火焰图的脚本,对二进制文件main进行10秒的采样,然后生成火焰图。
    非root用户需要加sudo。

    perf record -g ./test sleep 10
    perf script -i perf.data &> perf.unfold
    #火焰图的两个功能
    ./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
    ./FlameGraph/flamegraph.pl perf.folded > perf.svg

我自己的:

sudo perf record -g ./build_pc/dead_reckoning sleep 10
perf script -i perf.data &> perf.unfold
/home/yj/sda/third_party/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
/home/yj/sda/third_party/FlameGraph/flamegraph.pl perf.folded > perf.svg
在这里插入图片描述

上面的方式中,[unknown] 出现过多,可考虑将 -g(默认为 fp) 修改为 --call-graph。可参考 使用 perf 进行性能分析时如何获取准确的调用栈

-优点缺点
fpNone默认 fp 被优化掉了根本不可用。
lbr高效准确需要较新的 Intel CPU 才有此功能;2. 能记录的调用栈深度有限。
dwarf准确1. 开销相对较大;2. 需要编译时附加了调试信息。

sudo perf record --call-graph dwarf ./build_pc/dead_reckoning sleep 10
sudo perf script -i perf.data &> perf.unfold
/home/yj/sda/third_party/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
/home/yj/sda/third_party/FlameGraph/flamegraph.pl perf.folded > perf.svg
在这里插入图片描述

4. 从火焰图可以获得的信息

  • 调用栈从下往上,下层为父类,上层为子类。
  • 点击父类缩小,点击子类放大。
  • 只关注自己实现的函数名,忽略标准库中的函数
  • 总结一下,火焰图的宽度用于比较不同函数或代码路径的性能,而高度用于显示函数调用堆栈的深度

5. 生成火焰图常见问题

  1. Stack count is low (1). Did something go wrong?
    -> sudo perf script 时没加 root 权限。

这篇关于C++分析程序各模块耗时-perf火焰图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

Python中re模块结合正则表达式的实际应用案例

《Python中re模块结合正则表达式的实际应用案例》Python中的re模块是用于处理正则表达式的强大工具,正则表达式是一种用来匹配字符串的模式,它可以在文本中搜索和匹配特定的字符串模式,这篇文章主... 目录前言re模块常用函数一、查看文本中是否包含 A 或 B 字符串二、替换多个关键词为统一格式三、提

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Visual Studio 2022 编译C++20代码的图文步骤

《VisualStudio2022编译C++20代码的图文步骤》在VisualStudio中启用C++20import功能,需设置语言标准为ISOC++20,开启扫描源查找模块依赖及实验性标... 默认创建Visual Studio桌面控制台项目代码包含C++20的import方法。右键项目的属性: