如何分析CPU占用率性能问题?

基本概念

cpu频率

CPU每隔固定周期会发出timer interrupt (时钟中断),CPU的频率HZ用来定义每秒钟产生多少个时钟中断

CPU时间片

等于1/HZ, 是CPU可以分辨的最小时间间隔

CPU占用率

在一定时间内,进程占用的CPU时间片总和 / 总的CPU时间片

单核CPU占用率/总CPU占用率

现代CPU一般是多核心,而进程也是多线程的,那么进程占用的时间片一般情况下是所有线程占用的所有时间片的总和,但是分母却有两种定义:一种是执行的总时间,也可以认为是一个核心的总的时间片,另一种是所有CPU核心的时间片总和,也就是执行的总时间*核心数。

注意:核心数是逻辑核数!!!也就是常说的 x核2*x线程中的2*x!!!

所以,二者的换算关系是: 单核CPU占用率 = 总CPU占用率 * 核心数

系统自带工具如何查看CPU占用率

Windows

Windows平台的自带工具显示的均是总CPU占用率

打开任务管理器后,同一个进程,在进程页面和详细信息页面会看到两个不同的CPU占用率,如下图,进程页面是43.7%,详细信息页面是25%,这两个值是什么关系,哪个又是准确的CPU占用率呢?

这里要先提到两个概念:CPU基准频率和当前频率,由于现代CPU都有超频功能,所以实时运行的CPU频率不一定是基准频率,在任务管理器的性能页面可以看到实时频率:

进程页面的值是用基准频率算的,详细信息页面是用实时频率算的,而且用实时的频率计算CPU占用率才是准确的,且二者有如下换算关系:

基准频率 * 进程页面cpu占用率 = 实际频率 * 详细信息cpu占用率

所以接下来提到windows平台上的CPU占用率均是和详细信息页面的占用率对应。

但是该页面的CPU占用把小数部分忽略掉了,如果CPU占用小于1%会被显示为0,推荐另外一个工具,可以显示小数点后两位:

https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer

MacOS

打开活动监视器,注意这个是单核CPU占用率

Visual Studio CPU占用率分析

分析过程

打开visual studio, 调试 -- 窗口 -- 显示诊断工具:

  1. 点击右下角"CPU使用率" 选项卡,点击全部中断,再点击打开详细信息,会弹出CPU使用率Tab页

  1. 可以点击筛选器,筛选某一些线程看,点应用后,CPU使用率Tab页上会即时更新,这样可以分析某个线程内部,不同的函数CPU占用的比率,注意,筛选某一个线程后,该线程的CPU占用变成了100%,线程内部的占用比例也随之变化。

  2. CPU使用率有4个视图,一般用后面3个,调用树可以看到不同线程内部的调用关系,默认情况下看这个,模块是看不同模块的CPU占用率,函数是看不同的函数的CPU占用率,如果一个函数被多线程调用,那这里的占用率是不同线程的总和。

一些其他概念

3种编译模式下,CPU性能分析结果比较

Debug模式下,每个函数除了自己的执行时间,还有额外的生成debug信息的执行时间;

默认Release模式(O2优化)下,很多函数名都看不到,无法进一步分析,

禁用优化的Release模式可以看到所有函数名,又没有额外的debug信息执行时间,推荐使用。

CPU总计和自CPU什么区别?

比如: void fun1() { fun2(); int i = 3;}, 如果fun1的CPU总计时间为1秒,自CPU时间为0.3秒,则意味着执行int i = 3;花了0.3s,fun2()花了0.7s,也就是说,如果一个函数还包含其他函数调用,那么CPU总计 = 包含的其他调用CPU时间 + 除此之外没有其他调用花费的CPU时间

基于此结论,如果某个函数不再调用其他函数,则这个函数的CPU总计一定等于自CPU

查看某个线程/函数的CPU占用率

  1. 选择某个区间后,会显示总的时间(4.268s)

  2. 然后点击打开详细信息,切换到调用树,会显示个总的进程占用的时间,单位是ms,这里是8374ms

所以这段时间内,该进程的单核CPU占用率为 8374/4268 = 196.2%

由于PC是4核8线程的,所以总CPU占用率是 196.2% / 8 = 24.5%

用以上方法可以计算任何 线程或函数的CPU占用率

如何查看某一行代码的CPU占用率

双击某个函数,或点击右边的这个图标,可以在下面显示具体某一行代码的CPU占用,如上图:

Xcode CPU占用率分析

分析过程

Xcode先attach上去,然后进到如下界面,点击Profile in instruments

点击profile,进入instruments界面,需要关注图中以下几个地方:

  1. 点击1. Time Profiler或 2.video_conference_sdk,下面出现具体的占比,其中Weight和Self Weight的概念和vs类似

  2. 如果想看某个线程或者函数的CPU占用率,可以选中某一部分,查看总的时间,然后再看profile中消耗的时间,两者一比即是单核CPU占用率,这个值和macOS自带的活动监视器中的CPU占用率是一致的

  1. 点击2,可以出现不同线程,点选某个线程,可以查看线程内部不同函数的CPU占用率,注意和visual studio一样,点完之后,这个线程就变成了100%,目前看起来只支持看某一个线程(vs可以同时看多个线程)

  2. 点击3,同样可以按thread或CPU筛选

  3. 点击4中某一行,可以在profile里面迅速定位到这一行所在的堆栈

  4. 注意,还有个5:Call Tree,

这里面常用的有Separate by Thread和Top Functions,按字面意思很好理解是干啥的,其他不常用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值