C++代码使用 gperftools 工具进行性能分析

news2024/9/24 16:26:07

文章目录

  • 前言
  • gperftools 是什么
  • 使用方法
    • 安装工具
    • 代码插桩引入工具
    • 代码修改
      • 关键代码
      • 完整示例
      • 编译链接
      • 启动分析程序
  • 数据分析
  • 总结

前言

一直想用 gperftools 做一下性能方面的尝试,之前一直忙着开发,目前已经到了后期,忙里抽闲亲自操作一遍,从安装到分析做个简单的记录,以便后续拿来直接用。

gperftools 是什么

gperftools 是Google开发的用来进行代码性能分析工具,其实他是一系列高性能多线程 malloc() 实现的集合,同时添加了一些精巧的性能分析工具。

gperftools

使用gperftools工具可以通过采样的方式生成上面这种图形化的代码性能分析结果,便于我们分析程序性能瓶颈。

使用方法

C++程序按照代码插桩的方式引入了gperftools工具,不过这个工具需要单独安装,为了生成图形化的分析结果,还需要安装一些依赖库,下面简述以下使用功能步骤。

安装工具

  1. 安装编译所需基础软件

    sudo apt install autoconf automake libtool
    
  2. 安装graphviz,用于图形化显示分析结果

    sudo apt install graphviz
    
  3. 安装libunwind, 这个库提供了可用于分析程序调用栈的 API

    cd /tmp
    wget https://github.com/libunwind/libunwind/releases/download/v1.6.2/libunwind-1.6.2.tar.gz
    tar -zxvf libunwind-1.6.2.tar.gz
    cd libunwind-1.6.2
    ./configure
    make -j4
    sudo make install
    cd /tmp
    rm -rf libunwind-1.6.2.tar.gz libunwind-1.6.2
    
  4. 安装gperftools

    cd /tmp
    wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.10/gperftools-2.10.tar.gz
    tar -zxvf gperftools-2.10.tar.gz
    cd gperftools-2.10
    ./configure
    make -j4
    sudo make install
    cd ~
    rm -rf gperftools-2.10.tar.gz gperftools-2.10
    
  5. 刷新动态装入程序所需的链接和缓存文件

    sudo ldconfig
    

代码插桩引入工具

代码修改

主要在源程序中引入头文件,并且在待测试逻辑前后添加启动分析和结束分析的语句就行了,对于服务类程序,因为要一直运行,可以通过kill信号通知来开启和关闭性能分析。

关键代码

	#include <gperftools/profiler.h> // 引入头文件
	...
	ProfilerStart("cpp_demo.prof");  // 启动分析
	...
	ProfilerStop();                  // 结束分析
	...

完整示例

	#include <iostream>
	#include <gperftools/profiler.h>
	
	static void sig(int sig) // kill -10 pid to trigger
	{
	    static bool b = false;
	    if (!b)
	        ProfilerStart("cpp_demo.prof");
	    else
	        ProfilerStop();
	
	    b= !b;
	}
	
	int main(int argc, char* argv[])
	{
	    signal(SIGUSR1, sig);
	
	    while (true)
	    {
	        std::this_thread::sleep_for(std::chrono::milliseconds(1));
	        //..
	        std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(
	                std::chrono::system_clock::now().time_since_epoch()).count() << std::endl;
	    }
	
	    return 0;
	}

编译链接

编译时我们需要将 profiler 库和 libunwind 库链接到可执行程序,如果使用 cmake来构建,那么 CMakeLists 文件中的语句为:

	target_link_libraries(${PROJECT_NAME} profiler unwind)

启动分析程序

  1. 正常启动游戏服务器,通过ps命令查找到要分析的进程id,比如查找到demoserver的进程是 7217

    $ ps -ef | grep demoserver
    demo        7217       1 22 21:51 ?        00:00:18 ./demoserver-d
    
  2. 通过kill命令传递自定义信号10的方式启动和关闭分析程序,第一次运行命令是启动,第二次运行相同的命令是关闭,两次命令之间是分析的时间段

    $ kill -10 7217
    
  3. 关闭分析程序之后,会在可执行程序所在目录生成 cpp_demo.porf 文件,可以使用下面命令将结果图形化

    $ pprof --pdf demoserver cpp_demo.prof > demoserver.pdf
    Using local file demoserver.
    Using local file cpp_demo.prof.
    Dropping nodes with <= 1 samples; edges with <= 0 abs(samples)
    
  4. 最终生成的 demoserver.pdf 文件就是我们要用的分析结果,如文章开头所示。

数据分析

上面提到了生成pdf图,其实可以生成txt文本的,只要修改生成选项就可以,比如像这样:

# pprof --text demoserver cpp_demo.prof
Using local file demoserver.
Using local file cpp_demo.prof.
Total: 13 samples
       3  21.4%  21.4%        3  21.4% SpinLock::Unlock (inline)
       3  21.4%  42.9%        3  21.4% __GI_madvise
       2  14.3%  57.1%        2  14.3% SpinLock::Lock (inline)
       1   7.1%  64.3%        1   7.1% TCMalloc_PageMap2::get (inline)
       ...

上述文本数据每行包含6列数据,依次为:

  1. 分析样本数量(不包含其他函数调用)
  2. 分析样本百分比(不包含其他函数调用)
  3. 目前为止的分析样本百分比(不包含其他函数调用)
  4. 分析样本数量(包含其他函数调用)
  5. 分析样本百分比(包含其他函数调用)
  6. 函数名(或者类名+方法名)

样本数量相当于消耗的CPU时间,整个函数消耗的CPU时间相当于包括函数内部其他函数调用所消耗的CPU时间,如果是分析最上面的pdf图,每个节点代表一个函数,包含2~3行数据:

  1. 函数名(或者类名+方法名)
  2. 不包含内部函数调用的样本数 (百分比)
  3. of 包含内部函数调用的样本数 (百分比) #如果没有内部调用函数则不显示

总结

  • gperftools 是可以通过采样的方式进行代码性能分析工具,可生成图形化结果便于我们分析程序性能瓶颈
  • 待分析程序中引入gperftools非常方便,但是需要单独安装这个工具
  • 程序引入时只需要添加头文件,在目标位置插入 ProfilerStart("cpp_demo.prof");ProfilerStop(); 语句即可
  • 对于服务类程序通常不会直接结束,可以通过 kill 命令传递信号的方式来启动和关闭分析程序
==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

可能终于有一天 刚好遇见爱情
可能永远在路上 有人奋斗前行
可能一切的可能 相信才有可能
可能拥有过梦想 才能叫做青春

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

战争教育策略游戏 MiracleGame,开启新阶段重塑生态和玩法

香港 Web3 区块链周刚刚在一片喧嚣中结束。各路大V、KOL 们的 report 都对 GameFi 的前景非常自信。2021-2023年期间&#xff0c;大量资金涌入 GameFi 赛道&#xff0c;GameFi 一旦爆发将会是现象级的出圈事件。 MiracleGame 是一款基于 BNB Chain 构建的英雄和元神主题的战争教…

CorelDRAW2023最新版本图像设计软件

CorelDRAW 2023作为最新版的图像设计软件,在功能上做了较大提升,主要新的功能特性如下: 1. 全新界面设计:采用简约现代的 UI 设计,菜单和工具重新组织,更加直观易用。提供自动提示与设计指导,易于上手。 2. 智能工具与提示:运用 AI技术对用户操作行为和设计习惯进行分析,给出…

【AIGC】手把手使用扩散模型从文本生成图像

手把手使用扩散模型从文本生成图像 从 DALLE 到Stable Diffusion使用diffusers package从文本prompt生成图像参考资料 在这篇文章中&#xff0c;我们将手把手展示如何使用Hugging Face的diffusers包通过文本生成图像。 从 DALLE 到Stable Diffusion DALLE2是收费的&#xff0c…

Python数据分析第02课:环境准备

如果希望快速开始使用 Python 处理数据科学相关的工作&#xff0c;建议大家直接安装 Anaconda&#xff0c;然后使用 Anaconda 中集成的 Notebook 或 JupyterLab 工具来编写代码。因为对于新手来说&#xff0c;先安装官方的 Python 解释器&#xff0c;再逐个安装工作中会使用到的…

【JAVA】easyExcel导出导入使用

EasyExcel是阿里巴巴开源插件之一&#xff0c;主要解决了poi框架使用复杂&#xff0c;sax解析模式不容易操作&#xff0c;数据量大起来容易OOM&#xff0c;解决了POI并发造成的报错。主要解决方式&#xff1a;通过解压文件的方式加载&#xff0c;一行一行地加载&#xff0c;并且…

【剑指 offer】数组中出现次数超过一半的数字

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;算法训练营&#x1f447; 数 组 中 出 现 次 数 超 过 一 半 的 数 字 核心考点: 数组使用&#xff0c;简单算法的设计 描述&#xff1a; 给一个长度为 n 的数组&#xff0c;数组中有一个数字出现的次数超…

php:php-fpm平滑重启为什么无效

一、问题 今天修改了fpm一些配置&#xff0c;需要上线重启fpm&#xff0c;但是发现一瞬间出现很多502的错误请求&#xff0c;查看日志发现以下错误 fpm&#xff1a;重启日志 nginx&#xff1a;错误日志 2023/04/23 15:19:00 [error] 9#0: *1893053661 recv() failed (104: Co…

【服务器数据恢复】重装系统导致分区无法访问的数据恢复案例

服务器数据恢复环境&#xff1a; 磁盘柜raid卡15块磁盘组建一组raid5磁盘阵列&#xff0c;划分2个lun&#xff1b; 上层操作系统划分若干分区&#xff0c;通过LVM扩容方式将其中一个分区加入到了root_lv中&#xff0c;其他分区格式化为XFS文件系统。 服务器故障&#xff1a; 为…

S/MIME电子邮件证书,符合FDA邮件安全要求

美国食品和药物管理局 &#xff08;FDA&#xff09;要求合作伙伴提交或接收电子监管信息时&#xff0c;必须使用数字证书保障通信安全。 01 为什么FDA使用数字证书保障通信安全&#xff1f; 为了维护数据完整性、准确性,有组织地管理文件,FDA为接受机构的电子监管提交设置了电子…

基于开源 web3引擎的三维系统的开发

目录 结合图像特征的平滑恢复技术 1.开发步骤 &#xff12; 应用案例开发 结束语 应用 &#xff37;&#xff45;&#xff42;&#xff13;&#xff24; 引擎开发的计算机仿真系统或虚拟现实系统均需在 &#xff37;&#xff45;&#xff42; 浏览 器 上 运 行 &#xff0…

MII、 RMII、 GMII、 RGMII 接口介绍

1、RGMII 接口概要 以太网的通信离不开物理层 PHY 芯片的支持&#xff0c;以太网 MAC 和 PHY 之间有一个接口&#xff0c;常用的接口有MII、 RMII、 GMII、 RGMII 等。 MII&#xff08;Medium Independent Interface&#xff0c; 媒体独立接口&#xff09;&#xff1a; MII 支持…

技术招聘演化论:怎样从纸上答题升级到实战编程?

创新赛道的出现 一些企业或许已经对招聘管理系统&#xff08;Applicant Tracking System&#xff0c;简称 ATS&#xff09;有一定了解&#xff0c;ATS 可以帮助企业管理招聘流程&#xff0c;其中包括发布招聘信息、接收简历、筛选候选人和安排面试等。在中国&#xff0c;一些知…

seata1.6.0 单机,集群搭建 基于nacos注册中心 mysql数据库

seata1.6.0 单机&#xff0c;集群搭建 基于nacos注册中心 mysql数据库 大纲 1 单机搭建2 集群搭建 由于项目中的dubbo版本为2.6.0 故客户端程序&#xff08;TM RM&#xff09;使用seata-all 1.4.2 &#xff0c;服务端&#xff08;TC&#xff09;使用seata-server-1.6.0.zip …

SQL Server基础 第六章 聚合函数和分组查询

前言 在数据查询的很多场合&#xff0c;除了需要显示数据表的原始数据&#xff0c;还需要对这些数据进行分析、汇总以及求极值等&#xff0c; 如获取公司员工的人数、工资总额、最高工资、最低工资和平均工资等。本章我们将通过学习SQL Server 聚合函数轻松获取上述数据。另外&…

基于Java+SpringBoot+vue学生学习平台详细设计实现

基于JavaSpringBootvue学生学习平台详细设计实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目…

软件架构的演进(超详细)

文章目录 前言1、什么是单体架构2、分布式架构3、SOA架构4、微服务架构总结 前言 之前对各种架构一直有所了解&#xff0c;但也只是了解&#xff0c;没有过多的研究为什么架构在慢慢演进&#xff0c;新架构代替老架构的理由是什么&#xff0c;而刚好最近学习了一下架构的演进过…

人工智能会取代人工翻译吗?

当今社会正处于语言和技术高速发展的阶段&#xff0c;因此语言和技术的碰撞是不可避免的——甚至有些人说这种碰撞已经发生了&#xff0c;我们只是在等待尘埃落定。数字化、物联网、人工智能和机器学习&#xff0c;以及更进一步——智能手机、语音识别&#xff0c;以及互联网和…

27《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》中文分享

​《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》 本人能力有限&#xff0c;如果错误欢迎批评指正。 第六章&#xff1a;The principles of protein folding kinetics &#xff08;蛋白质折叠动力学的原理&#xff09; 整个二级结构通常作为一个单…

JS规范及常见问题

数字和字符串不能混合使用。 做加减法可能出错 "1"1 "11"做判断可能出错 "2"<"11"false几种for循环的使用: for(var i0;i<list.length;i): es5,需要拿到下标时、遍历非标准数组如FileList时for(var i in obj): es5,遍历对象时…

SpringBoot接口传递自定义参数,参数解析器

Hi I’m Shendi SpringBoot接口传递自定义参数&#xff0c;参数解析器 简介 我的需求&#xff1a;编写了一个日志微服务&#xff0c;使用方式是 创建日志对象 - 日志流程 - 完成日志对象&#xff0c;这样的方式使用时就需要在每个接口都去创建和完成一下&#xff0c;多出了一点…