如何快速定位CPU性能瓶颈 和 优化的几个思路

1. CPU性能指标

前面几篇博客已经讲过CPU相关的知识点,这里先大概总结一下,总括CPU性能指标:

CPU使用率:用户态CPU使用率(user)、低优先级用户态CPU使用率(nice)、系统CPU使用率、等待IO的CPU使用率(iowait)、软中断和硬中断的CPU使用率,还有在虚拟化环境中用到的窃取CPU使用率(steal)和客户CPU使用率(guest)。

平均负载:理想情况下,平均负载等于逻辑CPU个数,这表CPU刚好全部被利用,如果大于,说明平均负载比较重。

进程上下文切换:自愿上下文切换和非自愿上下文切换。过多的上下文切换,会将原本运行进程的CPU时间,消耗在寄存器、内核栈以及虚拟内存等数据的保存和恢复上,缩短进程真正运行时间,成为性能瓶颈。

CPU缓存命中率:CPU缓存速度介于CPU和内存之间,缓存的是热点的内存数据。这些缓存按照大小分为L1、L2 、L3等三级缓存,L1、L2常用在单核中,L3则用在多核中,大小依次增大,性能依次降低(当然比内存还好是好太多)。而它们的命中率,则是衡量CPU缓存复用情况,命中率越高,性能越好。

                                                          

2. 性能工具

活学活用,把性能指标和性能工具联系起来。

第一个维度,从CPU的性能指标出发,当你要查看某个性能指标时,要清楚知道可以使用哪些性能工具。

                                                

第二个维度,从工具出发,如果安装了某个工具,要知道这个工具能提供那些指标。

                                                

如下有展示了三个工具:top、vmstat、pidstat,他们支持的指标比较多。

                                               

这张图列出了三个工具分别提供的CPU性能指标,并用虚线表示关联关系,他们几乎包含了所有CPU性能指标。举几个例子能更容易理解:

第一个例子,pidstat输出的进程用户CPU使用率升高,会导致top输出的用户使用率升高。所以,当发现top输出的用户CPU使用率有问题,可以跟pidstat输出作对比,观察是否某个进程导致,最后再用进程分析工具来分析进程行为。

第二个例子,top输出的平均负载升高,可以跟vmstat输出的运行状态和不可中断状态进程数作对比,观察是那种负载导致的平均负载升高。如果是不可中断进程数增多,就需要做I/O分析,使用对应分析工具;如果是运行状态进程数增多,就要用pidstat和top找出处于运行状态的进程是谁,再用进程分析工具分析。

最后一个例子,当发现top输出的软中断CPU使用率升高,可以查看/proc/softirqs文件中各种类型软中断的变化情况,确定是哪类软中断的问题,比如是NET_RX导致的,可继续用网络分析工具sar、tcpdump分析。

3. CPU性能优化思路

进行性能优化时通常会面临三个问题:

怎么判断它是不是有效?优化后,到底提升多少性能?

性能问题通常不是独立出现,当出现多个问题时,应当先优化哪个?

提升性能方法不唯一,要选哪种,是不是一定选提升最大的那一种?

怎么去思量这几个问题,如何去解决:

第一个问题,确定性能的量化指标,以及优化前后的性能问题的测试对比。性能的量化指标有很多,CPU使用率、应用程序吞吐量、客户端请求的延迟等。秉持的原则就是不要局限于单一维度的指标。以web应用为例:

  • 应用程序维度,可以用吞吐量和请求延迟来评估应用性能。
  • 系统资源维度,可以用CPU使用率来评估系统的CPU使用情况。

之所以选择这两个维度,是因为应用程序和系统资源两者是相辅相成的。好的应用程序是性能优化的最终目的和结果,系统优化总是为应用程序服务的。系统资源的使用情况是影响应用程序性能的根源。

第二个问题,在性能测试领域,流传很广的一个说法是“二八原则”,也就是80%的问题是由20%代码导致的。先把所有性能问题分析一遍,找出最重要的、能最大提升性能的问题,从它开始,这样做的好处是,除了能最大提升性能,可能其他问题都不需要优化就能满足需求。就这样按照因果关系,排除掉有因果关系的性能问题后,再对剩下的问题优化。

通常剩下的问题很有可能不止一个,那么就要分别做性能测试,比较不同的优化效果后,选择最能提升性能的那个问题修复。这里推荐两个可以简化这个过程的方法:

第一、如果是系统资源达到了瓶颈,比如CPU使用率达到100%,那么首先优化的,一定是系统资源问题。

第二、针对不同类型的指标,首先优化由瓶颈导致的,性能指标变化幅度最大的问题。比如瓶颈产生后,用户CPU使用率提升10%,系统CPU使用率提升50%,这个时候应该首先优化系统CPU的使用。

第三个问题,一般选择能最大提升性能的方法,但是性能优化不是没有成本。性能优化通常会带来复杂度的提升,降低程序的可维护性,甚至会引发其他性能指标的异常。

清楚了以上三个问题后,接下来从应用程序和系统角度,来谈谈如何降低CPU使用率,提高CPU并行处理能力。

应用程序优化

编译器优化:比如gcc编译器,提供了优化选项-O2,开启后会自动对应用程序代码进行优化。

算法优化:使用复杂度低的算法,可以明显加快处理速度。

异步处理:可以避免程序因等待某个资源而一直阻塞,从而提升程序并发处理能力。比如,事件通知替换掉轮询,可以避免轮询耗费的CPU问题。

多线程代替多进程:可以降低上下文切换成本。

善用缓存:经常访问的数据或者计算过程中的步骤,放到内存中,下次用时直接取,加快处理速度。

系统优化

从系统的角度来说,优化CPU的运行,一方面充分利用CPU缓存的本地性,减速缓存访问;另一方面,控制进程的CPU使用情况,减少进程间的相互影响。

CPU绑定:把进程绑定到一个或多个CPU上,可以提高CPU缓存的命中率,减少跨CPU调度带来的上下文切换问题。

CPU独占:跟绑定类似,进一步将CPU分组,根据CPU亲和性机制为其分配进程,这些CPU由指定进程独占,其他进程不能去使用它。

优先级调整:使用nice调整进程的优先级,适当的调低非核心应用的优先级,增高核心应用的优先级,可以确保核心应用得到优先处理。

为进程设置资源限制:使用Linux cgroups 来设置CPU使用上限,可以防止因某个应用自身的问题,耗尽系统资源。

NUMA(Non-Uniform Memory Access)优化:支持 NUMA 的处理器会被划分为多个node,每个node都有自己的本地内存空间,就是让CPU尽可能只访问本地内存。

中断负载均衡:开启 irqbalance 服务或者配置 smp_affinity,可以把中断处理过程负载均衡到多个CPU。

最后,切忌过早优化。性能优化最好是逐步完善,动态进行,不追求一步到位,而要首先保证能满足当前的性能需求。出现性能问题,先找出最重要的,可以获得最大性能提升的问题,然后再从应用程序和系统两方面入手优化。

 

以上是学习极客时间专栏(倪朋飞:Linux性能优化实战)的个人总结

https://time.geekbang.org/column/intro/140

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值