cpu 性能优化思路

cpu 性能优化思路


前言

虽然 CPU 的性能指标很多,相应的性能分析工具也很多,但理解了各种指标的含义后,你就会发现它们其实都有一定的关联。顺着这些关系往下理解,你就会发现,掌握这些常用的瓶颈分析套路,其实并不难。在找到 CPU 的性能瓶颈后,下一步要做的就是优化了,也就是找出充分利用 CPU 的方法,以便完成更多的工作。今天,我就来说说,优化 CPU 性能问题的思路和注意事项。
在这里插入图片描述

在我们历经千辛万苦,通过各种性能分析方法,终于找到引发性能问题的瓶颈后,是不是立刻就要开始优化了呢?别急,动手之前,你可以先看看下面这三个问题。

  • 首先,既然要做性能优化,那要怎么判断它是不是有效呢?特别是优化后,到底能提升多少性能呢?
  • 第二,性能问题通常不是独立的,如果有多个性能问题同时发生,你应该先优化哪一个呢?
  • 第三,提升性能的方法并不是唯一的,当有多种方法可以选择时,你会选用哪一种呢?是不是总选那个最大程度提升性能的方法就行了呢?

一、性能优化方法论

cpu性能优化工具

根据cpu性能指标和工具的对应关系,我做了两个表格,方便你梳理关系和理解记忆。当然,你也可以当成“指标工具”和“工具指标”指南来用,在需要时直接查找。第一个表格,从cpu指标出发,列举了哪些性能工具可以提供这些指标。这样,在实际排查性能问题时,你就可以清楚知道,究竟要用什么工具来辅助分析,提供你想要的指标。
在这里插入图片描述
第二个表格,从性能工具出发,整理了这些常见工具能提供的cpu指标。掌握了这个表格,你可以最大化利用已有的工具,尽可能多地找到你要的指标。这些工具的具体使用方法并不用背,你只要知道有哪些可用的工具,以及这些工具提供的基本指标。真正用到时, man 一下查它们的使用手册就可以了。
在这里插入图片描述

性能优化是否有效

性能评估可能有多重指标,性能问题可能会多个同时发生,而且,优化某一个指标的性能,可能又导致其他指标性能的下降。那么,面对这种复杂的情况,我们该怎么办呢?接下来,我们就来深入分析这三个问题。怎么评估性能优化的效果?首先,来看第一个问题,怎么评估性能优化的效果。

我们解决性能问题的目的,自然是想得到一个性能提升的效果。为了评估这个效果,我们需要对系统的性能指标进行量化,并且要分别测试出优化前、后的性能指标,用前后指标的变化来对比呈现效果。我把这个方法叫做性能评估“三步走”。

确定性能的量化指标。测试优化前的性能指标。测试优化后的性能指标。先看第一步,性能的量化指标有很多,比如 CPU 使用率、应用程序的吞吐量、客户端请求的延迟等,都可以评估性能。那我们应该选择什么指标来评估呢?我的建议是不要局限在单一维度的指标上,你至少要从应用程序系统资源这两个维度,分别选择不同的指标。比如,以 Web 应用为例:

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

之所以从这两个不同维度选择指标,主要是因为应用程序和系统资源这两者间相辅相成的关系。好的应用程序是性能优化的最终目的和结果,系统优化总是为应用程序服务的。所以,必须要使用应用程序的指标,来评估性能优化的整体效果。系统资源的使用情况是影响应用程序性能的根源。所以,需要用系统资源的指标,来观察和分析瓶颈的来源。至于接下来的两个步骤,主要是为了对比优化前后的性能,更直观地呈现效果。如果你的第一步,是从两个不同维度选择了多个指标,那么在性能测试时,你就需要获得这些指标的具体数值。

不过,在进行性能测试时,有两个特别重要的地方你需要注意下。

  • 第一,要避免性能测试工具干扰应用程序的性能。
  • 第二,避免外部环境的变化影响性能指标的评估。

多个性能问题同时存在,要怎么选择?

再来看第二个问题,开篇词里我们就说过,系统性能总是牵一发而动全身,所以性能问题通常也不是独立存在的。那当多个性能问题同时发生的时候,应该先去优化哪一个呢?

在性能测试的领域,流传很广的一个说法是“二八原则”,也就是说 80% 的问题都是由 20% 的代码导致的。只要找出这 20% 的位置,你就可以优化 80% 的性能。所以,我想表达的是,并不是所有的性能问题都值得优化。我的建议是,动手优化之前先动脑,先把所有这些性能问题给分析一遍,找出最重要的、可以最大程度提升性能的问题,从它开始优化。这样的好处是,不仅性能提升的收益最大,而且很可能其他问题都不用优化,就已经满足了性能要求。那关键就在于,怎么判断出哪个性能问题最重要。

这其实还是我们性能分析要解决的核心问题,只不过这里要分析的对象,从原来的一个问题,变成了多个问题,思路其实还是一样的。所以,你依然可以用我前面讲过的方法挨个分析,分别找出它们的瓶颈。分析完所有问题后,再按照因果等关系,排除掉有因果关联的性能问题。最后,再对剩下的性能问题进行优化。如果剩下的问题还是好几个,你就得分别进行性能测试了。比较不同的优化效果后,选择能明显提升性能的那个问题进行修复。这个过程通常会花费较多的时间,这里,我推荐两个可以简化这个过程的方法。

  • 第一,如果发现是系统资源达到了瓶颈,比如 CPU 使用率达到了100%,那么首先优化的一定是系统资源使用问题。完成系统资源瓶颈的优化后,我们才要考虑其他问题。
  • 第二,针对不同类型的指标,首先去优化那些由瓶颈导致的,性能指标变化幅度最大的问题。比如产生瓶颈后,用户 CPU 使用率升高了10%,而系统 CPU 使用率却升高了 50%,这个时候就应该首先优化系统 CPU 的使用。

有多种优化方法时,要如何选择?

接着来看第三个问题,当多种方法都可用时,应该选择哪一种呢?是不是最大提升性能的方法,一定最好呢?一般情况下,我们当然想选能最大提升性能的方法,这其实也是性能优化的目标。但要注意,现实情况要考虑的因素却没那么简单。最直观来说,性能优化并非没有成本。性能优化通常会带来复杂度的提升,降低程序的可维护性,还可能在优化一个指标时,引发其他指标的异常

也就是说,很可能你优化了一个指标,另一个指标的性能却变差了。一个很典型的例子是 DPDK(Data Plane Development Kit)。DPDK 是一种优化网络处理速度的方法,它通过绕开内核网络协议栈的方法,提升网络的处理能力。不过它有一个很典型的要求,就是要独占一个 CPU 以及一定数量的内存大页,并且总是以 100% 的 CPU 使用率运行。所以,如果你的 CPU 核数很少,就有点得不偿失了。所以,在考虑选哪个性能优化方法时,你要综合多方面的因素。切记,不要想着“一步登天”,试图一次性解决所有问题;也不要只会“拿来主义”,把其他应用的优化方法原封不动拿来用,却不经过任何思考和分析。

二、CPU 优化

清楚了性能优化最基本的三个问题后,我们接下来从应用程序和系统的角度,分别来看看如何才能降低 CPU 使用率,提高 CPU 的并行处理能力。

应用程序优化

首先,从应用程序的角度来说,降低 CPU 使用率的最好方法当然是,排除所有不必要的工作,只保留最核心的逻辑。比如减少循环的层次、减少递归、减少动态内存分配等等。除此之外,应用程序的性能优化也包括很多种方法。

  • 编译器优化:很多编译器都会提供优化选项,适当开启它们,在编译阶段你就可以获得编译器的帮助,来提升性能。比如, gcc 就提供了优化选项-O2,开启后会自动对应用程序的代码进行优化。
  • 算法优化:使用复杂度更低的算法,可以显著加快处理速度。比如,在数据比较大的情况下,可以用 O(nlogn)的排序算法(如快排、归并排序等),代替 O(n^2) 的排序算法(如冒泡、插入排序等)。
  • 异步处理:使用异步处理,可以避免程序因为等待某个资源而一直阻塞,从而提升程序的并发处理能力。比如,把轮询替换为事件通知,就可以避免轮询耗费CPU 的问题。多线程代替多进程:前面讲过,相对于进程的上下文切换,线程的上下文切换并不切换进程地址空间,因此可以降低上下文切换的成本。
  • 善用缓存:经常访问的数据或者计算过程中的步骤,可以放到内存中缓存起来,这样在下次用时就能直接从内存中获取,加快程序的处理速度。

系统优化

从系统的角度来说,优化 CPU 的运行,一方面要充分利用 CPU 缓存的本地性,加速缓存访问;另一方面,就是要控制进程的 CPU 使用情况,减少进程间的相互影响。具体来说,系统层面的 CPU 优化方法也有不少,这里我同样列举了最常见的一些方法,方便你记忆和使用。

  • CPU 绑定:把进程绑定到一个或者多个 CPU 上,可以提高 CPU 缓存的命中率,减少跨 CPU 调度带来的上下文切换问题。
  • CPU 独占:跟 CPU 绑定类似,进一步将 CPU 分组,并通过 CPU 亲和性机制为其分配进程。这样,这些 CPU就由指定的进程独占,换句话说,不允许其他进程再来使用这些 CPU。
  • 优先级调整:使用 nice调整进程的优先级,正值调低优先级,负值调高优先级。优先级的数值含义前面我们提到过,忘了的话及时复习一下。在这里,适当降低非核心应用的优先级,增高核心应用的优先级,可以确保核心应用得到优先处理。
  • 为进程设置资源限制:使用 Linux cgroups 来设置进程的 CPU 使用上限,可以防止由于某个应用自身的问题,而耗尽系统资源。
  • NUMA(Non-Uniform Memory Access)优化:支持 NUMA 的处理器会被划分为多个 node,每个 node都有自己的本地内存空间。NUMA 优化,其实就是让 CPU 尽可能只访问本地内存。
  • 中断负载均衡:无论是软中断还是硬中断,它们的中断处理程序都可能会耗费大量的 CPU。开启 irqbalance 服务或者配置smp_affinity,就可以把中断处理过程自动负载均衡到多个 CPU 上。

总结

今天,我带你梳理了常见的 CPU 性能优化思路和优化方法。发现性能问题后,不要急于动手优化,而要先找出最重要的、可以获得最大性能提升的问题,然后再从应用程序和系统两个方面入手优化。这样不仅可以获得最大的性能提升,而且很可能不需要优化其他问题,就已经满足了性能要求。但是记住,一定要忍住“把 CPU 性能优化到极致”的冲动,因为 CPU 并不是唯一的性能因素。在后续的文章中,我还会介绍更多的性能问题,比如内存、网络、I/O 甚至是架构设计的问题。如果不做全方位的分析和测试,只是单纯地把某个指标提升到极致,并不一定能带来整体的收益。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值