【Linux 性能优化系列】Linux 性能优化 -- CPU 性能优化综述
【1】CPU 性能指标
CPU 使用率
描述了非空闲时间占总 CPU 时间的百分比;
用户 CPU 使用率,包括用户态 CPU 使用率(user)和低优先级用户态 CPU 使用率(nice),表示 CPU 在用户态运行的时间百分比;用户 CPU 使用率高,通常说明有应用程序比较繁忙;
系统 CPU 使用率,表示 CPU 在内核态运行的时间百分比(不包括中断);系统 CPU 使用率高,说明内核比较繁忙;
等待 I/O 的 CPU 使用率,通常也称为 iowait,表示等待 I/O 的时间百分比;iowait 高,通常说明系统与硬件设备的 I/O 交互时间比较长;
软中断和硬中断的 CPU 使用率,分别表示内核调用软中断处理程序、硬中断处理程序的时间百分比;它们的使用率高,通常说明系统发生了大量的中断;
虚拟化环境中的窃取 CPU 使用率(steal)和客户 CPU 使用率(guest),分别表示被其他虚拟机占用的 CPU 时间百分比和运行客户虚拟机的 CPU 时间百分比;
平均负载(Load Average)
描述系统的平均活跃进程数,反应了系统的整体负载情况,主要包括三个数值,分别指过去 1 分钟、过去 5 分钟和过去 15 分钟的平均负载;理想情况下,平均负载等于逻辑 CPU 个数,这表示每个 CPU 都恰好被充分利用;如果平均负载大于逻辑 CPU 个数,就表示负载比较重了;
进程上下文切换
1. 无法获取资源而导致的自愿上下文切换;2. 被系统强制调度导致的非自愿上下文切换;
CPU 缓存的命中率
【2】CPU 相关性能工具
【2.1】根据性能指标确定性能工具
【2.2】根据性能工具确定可以检测的指标
【2.3】CPU 性能工具与 CPU 性能指标之间的关联性
【3】CPU 性能优化的基本思路
【3.1】CPU 性能优化方法论
【3.1.1】性能优化前需要思考的问题
1. 既然要做性能优化,怎么判断是不是有效?特别是优化后,到底能提升多少性能呢?
2. 性能问题通常不是独立的,如果有多个性能问题同时发生,应该先优化哪一个呢?
3. 提升性能的方法并不是唯一的,当有多种方法可以选择时,应该选用哪一种呢?是不是总选那个最大程度提升性能的方法就行了呢?
【3.1.2】性能优化效果评价
1. 确定性能的量化指标
不要局限在单一维度的指标上,至少要从应用程序和系统资源这两个维度,分别选择不同的指标;
2. 测试优化前的性能指标
3. 测试优化后的性能指标
检测性能注意事项
1. 避免性能测试工具干扰应用程序的性能
2. 避免外部环境的变化影响性能指标的评估
【3.1.3】多性能问题的取舍
并不是所有的性能问题都值得优化,先把所有这些性能问题给分析一遍,找出最重要的、可以最大程度提升性能的问题开始优化;
【3.1.4】多种优化方法的取舍
性能优化并非没有成本,性能优化通常会带来复杂度的提升,降低程序的可维护性,可能在优化一个指标时,引发其他指标的异常;
【4】CPU 优化方法
应用程序优化
排除所有不必要的工作,只保留最核心的逻辑,比如减少循环的层次、减少递归、减少动态内存分配等等;
1. 编译器优化,很多编译器都会提供优化选项,适当开启它们,在编译阶段你就可以获得编译器的帮助,来提升性能;
比如,gcc 就提供了优化选项 -O2,开启后会自动对应用程序的代码进行优化;
2. 算法优化,使用复杂度更低的算法,可以显著加快处理速度;
比如,在数据比较大的情况下,可以用 O(nlogn) 的排序算法(如快排、归并排序等),代替 O(n^2) 的排序算法(如冒泡、插入排序等);
3. 异步处理,使用异步处理,可以避免程序因为等待某个资源而一直阻塞,从而提升程序的并发处理能力;
比如,把轮询替换为事件通知,就可以避免轮询耗费 CPU 的问题;
4. 多线程代替多进程,相对于进程的上下文切换,线程的上下文切换并不切换进程地址空间,因此可以降低上下文切换的成本;
5. 善用缓存,经常访问的数据或者计算过程中的步骤,可以放到内存中缓存起来,这样在下次用时就能直接从内存中获取,加快程序的处理速度;
系统优化
1. CPU 绑定,把进程绑定到一个或者多个 CPU 上,可以提高 CPU 缓存的命中率,减少跨 CPU 调度带来的上下文切换问题;
2. CPU 独占,进一步将 CPU 分组,并通过 CPU 亲和性机制为其分配进程,从而这些 CPU 就由指定的进程独占,即不允许其他进程再来使用这些 CPU;
3. 优先级调整,使用 nice 调整进程的优先级,正值调低优先级,负值调高优先级;因此适当降低非核心应用的优先级,增高核心应用的优先级,可以确保核心应用得到优先处理;
4. 为进程设置资源限制,使用 Linux cgroups 来设置进程的 CPU 使用上限,可以防止由于某个应用自身的问题,而耗尽系统资源;
5. NUMA(Non-Uniform Memory Access)优化,支持 NUMA 的处理器会被划分为多个 node,每个 node 都有自己的本地内存空间;NUMA 优化,其实就是让 CPU 尽可能只访问本地内存;
6. 中断负载均衡,无论是软中断还是硬中断,中断处理程序都可能会耗费大量的 CPU;开启 irqbalance 服务或者配置 smp_affinity,就可以把中断处理过程自动负载均衡到多个 CPU 上;
参考致谢
本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。