linux 高性能学习笔记8
针对cup瓶颈的问题分析了很多,相应的分析工具也介绍了不少,但理解了各种指标的含义后,会发现他们之间是有一定关联性的。顺着关联是可以很快找到瓶颈所在。找到瓶颈下一步就是进行优化。
方法论
可以从下面三个问题出发来判断性能优化是否有效
- 如何判断性能优化的有效性?
- 性能问题通常不是独立问的,如果同时发生先优化哪一个?
- 提升性能的方法并不唯一的,当有多钟选择时,改选哪一种?
如果你能轻松的回答这三个问题就可以开始优化了
细化三个问题
- 如何评估性能效果
- 确定性能的量化指标
- cpu使用率
- 应用程序吞吐量
- 客户端请求的延迟
建议不要局限在单一纬度上来定指标 应用程序纬度:吞吐量和请求延迟 系统资源纬度:cpu使用率
- 测试优化前的性能指标
注意:
- 尽量避免性能测试工具干扰应用程序的性能,防止交叉污染
- 避免外部环境的变化影响性能指标的评估
- 测试优化后的性能指标
- 确定性能的量化指标
- 多个性能问题同时存在,要怎么选?
- 二八原则:80%的问题都是由20%的代码导致的,只要找到20%就可以了,并不是所有的性能问题都值得优化
- 如果资源达到瓶颈,比如cpu使用率到了100%,那么首先优化一定是系统资源使用问题。优化后再考虑其他问题。
- 针对不同类型的指标,首先优化那些由瓶颈导致的,性能指标变化幅度最大的问题,比如产生瓶颈后,用户cpu使用率升高了10%,而系统cpu使用率却升高了50%,这个时候首先应该优化cpu使用率。
- 二八原则:80%的问题都是由20%的代码导致的,只要找到20%就可以了,并不是所有的性能问题都值得优化
- 多种优化方法时,如何选择?
- 性能优化并非没有成本 当你优化一个指标,有可能另一个指标却上升了。
- 比如网络优化中的DPDK(Data Plane Development Kit)提升网络的处理能力。它需要独占一个cpu以及一定数量的内存大页,CPU核数较少是并不适合用这种优化。
几大优化方向
* CPU优化
- 应用程序优化:排除所有不必要的工作,只保留核心的逻辑。比如减少循环层次,减少递归,减少动态内存分配等等
- 编译器优化:gcc
- 算法优化:减少算法复杂度
- 异步处理:轮训改为事件通知
- 多线程代替多进程:减少上下文切换
- 善用缓存:减少磁盘操作,直接使用缓存
- 系统优化:
- cpu绑定:把进程绑定到一个或者多个cpu上,可以提高cpu缓存命中率,减少跨cpu调度带来的上下文切换
- cpu独占:类似绑定,独占cpu
- 优先级调整:减低非核心业务的应用优先级
- 为进程设置资源限制:使用linux cgroups 来设置进程的cpu使用上线。
- NUMA(Non-Uniform Memory Access)优化:支持NUMA的cup,会被划分为多个node,每个都有自己的本地内存地址。
- 中断负载均衡:开启irqbalance服务或者配置smp_affinity,把中断处理自动负载均衡到多个cpu
注意: 避免过早优化:
- 优化带来复杂性的提升,降低可维护性。
- 需求是动态变化的,要针对当前情况进行优化,是个动态的过程。