文档章节

如何做系统性能优化

陶邦仁
 陶邦仁
发布于 2015/11/09 17:00
字数 2171
阅读 426
收藏 5

#0 系列目录#

性能优化的目标是什么?不外乎两个:

  1. 时间性能:减小系统执行的时间
  2. 空间性能:减小系统占用的空间

#1 性能估算# 给定一个问题,往往会有多种设计方案,而方案评估的一个重要指标就是性能,如何在系统设计时估算而不是在程序执行时测试得到性能数据是系统架构设计的重要技能。性能估算有如下用途:

  1. 多种设计方案选择;

  2. 评价程序实现是否足够优化;

  3. 向框架/服务提供方提出性能要求的依据;

通过查看程序运行时CPU及网络的使用情况来评价程序是否足够优化,这也是一种很重要的方法。然而,这种方法掩盖了不优化的实现,如O(N)的算法被错误实现成O(N^2),网络收发冗余数据等。

性能评估需要假设程序的执行环境,如集群规模及机器配置,集群上其它服务占用资源的比例。首先,我们需要知道一些常见硬件的大致性能参数:

L1 cache reference                              0.5ns               CPU一级缓存
Branch mispredict                               5ns                 分支预测
L2 cache reference                              7ns                 CPU二级缓存
Mutex lock/unlock                               100ns
Main memory reference                           100ns               内存
Send 1M bytes over 1Gbps network                10ms                1G的宽带传输1MB
Read 1M sequentially from memory                0.25ms              内存读取1MB数据
Round trip within data center                   0.5ms
Disk seek                                       8~10ms              磁盘寻道
Read 1MB sequentially from disk                 20~25ms             磁盘读取1MB数据

其中,磁盘的性能指标专指分布式平台专用的大容量磁盘,寻道时间为8~10ms,顺序读取速率为40~50MB。某些产品线使用SCSI磁盘或者Flash盘,性能较好,评估时需查看硬件的性能参数。磁盘和网络都有一个特征,一次读写的数据量越大性能越好,这是由硬件特征及底层软件算法决定的,如tcp慢连接和磁盘寻道时间长。

#2 代码优化# 做代码优化前,先了解下硬件Cache:

  1. Cache Level:通常来说L1、L2的Cache集成在CPU里,L3的Cache放在CPU外
  2. Cache Size:它决定你能把多少东西放到Cache里,有Size就有竞争,就有替换,才有所谓优化的空间;
  3. Cache Type:I-Cache(指令),D-Cache(数据),TLB(MMU的Cache);

代码层次的优化主要从以下两个角度考虑问题:

  1. I-Cache优化:精简code path,简化调用关系,减少冗余代码等等;
  2. D-Cache优化:减少D-Cache的miss数量,增加有效数据访问

以下是一些技巧,可供参考:

  1. Code adjacency(把相关代码放在一起)。

这里有两层含义:一是相关源文件要放在一起;二是相关函数在object文件里面,也应该相邻。这样,可执行文件被夹在到内存里时,函数位置也是相邻的,同事还符合模块化编程的要求:高内聚,低耦合

  1. Cache line alignment(cache对齐)。

对齐Cache以减少潜在的一次读写,但这可能意味着内存的浪费,需要从空间和时间两方面衡量

  1. Branch prediction(分支预测)。

如果能预测那段代码有更高的执行概率,就能减少跳转次数(调整if和else的顺序?)。

  1. Data prefetch(数据预取)。

由CPU自动完成。

  1. Register parameters(寄存器参数)。

  2. Lazy computation(延时计算)。

最近不用的变量,不要急着去初始化(意味着可能执行复杂的构造),如果某个分支跳出了函数,这些动作就浪费了。COW(copy-on-write)就是一种延时计算的技术

  1. Early computation(提前计算)。

有些变量,计算一次就够了,任何加减乘除都会消耗CPU指令,尽量使用常数,而不是246060来表示一天的秒数。

  1. Inline(内联函数)。

  2. Macro(宏定义)。

  3. Allocation on stack(局部变量)。

避免在栈上申请大数组,其初始化和销毁的代价很高。

  1. Per-cpu data structure(非共享数据结构)。

避免共享量的锁,在thread local里,多核情况下使用局部变量会带来好处

  1. Reduce call path or call trace(减少函数调用层次)。

  2. Read&write split(读写分离)。

  3. Recude duplicated code(减少冗余代码)。

#3 工具优化# “工欲善其事,必先利其器”,如果没有工具的支持,性能优化难以实施,谁也不知道哪些地方是严重影响性能的主要矛盾。

使用性能优化的工具,需要考虑以下问题:

  1. 使用工具是否需要重新执行编译?
  2. 工具本身对测量结果的影响:工具对性能的影响必须在一个可接受的范围以内

工具能解决的问题:

  1. 建立性能基线,以作对比;
  2. 帮助定位性能瓶颈;
  3. 帮助验证优化方案;

性能测试工具一般由这么几种:

  1. 收集CPU的性能计数;
  2. 利用编译器的功能,在函数入口和出口加回调函数;
  3. 在代码中加入时间测量点;

#4 系统优化# 从系统层面去优化系统往往有更为明显的效果,优化之前,可以思考,是否能够通过扩展系统来达到提高性能的目的:

  1. Scale up:使用更强的硬件;
  2. Scale out:使用更多的组件;

如果升级硬件的方法就能解决问题,为什么还要使用修改代码,调整架构这样大风险的举措呢?(需要考虑成本)

以下是一些常用的系统优化的方法:

  1. Cache

Cache干什么?保存已经执行过的结果

Cache为什么有效?避免已计算过的开销,获取更快的访问。

Cache的难点在哪里?一是快速匹配;二是Cache容量有效,需要较好的替换策略

Cache在哪些情况下有效?时间局部性。即当前计算的结果,后续有可能使用到,如果没有时间局部性,反而对架构有害

  1. Lazy Computing

理念就是,不要做多余的事情,最常见的例子就是COW(copy-on-write):http://en.wikipedia.org/wiki/Copy-on-write

COW干什么?写时复制。

COW为什么有效?节省内存复制时间,均匀内存分配时间。

COW的难点在哪里?一是引用计数的使用;二是确认哪些内存是可以共享的。

  1. read ahead/pre-fetch预读:http://en.wikipedia.org/wiki/Readahead

预读干什么?提前准备所需要的数据。

预读为什么有效?减少等待内存的时间,相当于把多个操作集合成一个。

预读在哪些情况下有效?空间局部性。

  1. Asynchronous异步:http://en.wikipedia.org/wiki/Asynchronous_I/O

异步干什么?异步是一种通信方式,请求与应答分离。

异步为什么有效?消除等待时间。

异步的难点是什么?如何实现分布式状态机,如何使用回调,使异步时间到达后继续执行。

异步在哪些情况下有效?状态之间不能有强依赖关系。

  1. Polling轮询:http://en.wikipedia.org/wiki/Polling_(computer_science)

  2. Static memory pool(内存池):http://en.wikipedia.org/wiki/Static_memory_allocation

内存池干什么?提前分配内存以获取更好的性能,只是适应性可能会降低,并可能造成内存浪费。

内存池为什么有效?避免重复内存申请、释放开销。

内存池的难点是什么?分配多大的内存池,如何避免浪费都是需要考虑的问题。

内存池在哪些情况下有效?一是固定大小的内存需求,二是快速的分配与释放需求。

#5 总结# 性能优化只是系统的一个方面,它可能会和系统的其他要求有冲突,比如:

  1. 可读性:性能优化不能影响可读性,谁愿意维护不怎么漂亮的代码;
  2. 模块化:性能优化往往需要打破模块的边界,想想这是否值得;
  3. 可移植:隔离硬件相关的代码,尽量使用统一的API;
  4. 可维护:许多性能优化的技巧,会导致后来维护代码的人崩溃;

需要在性能优化和上述的几个要求之间做出tradeoff,不能一意孤行。

© 著作权归作者所有

陶邦仁
粉丝 1688
博文 420
码字总数 1483887
作品 0
海淀
技术主管
私信 提问
php职业规划

现在工作几年的php开发者都会有这样的迷茫,php开发多了,无外乎“增删改查调接口”,感觉每天的工作都是重复性的劳动,一点新意也没有,感觉技术上没有多大的长进了。真的是这样吗? 实际上...

成越
2016/09/01
93
0
PHP高级程序员所要掌握的技能

很多工作几年的php开发者都会有这样的迷茫,php开发多了,无外乎“增删改查调接口”,真的是这样吗? 实际上开发者除了把自己当成php程序员,更应该关注php以外的东西,将自己定位于能熟练使...

小田天
2016/11/18
107
0
AI算力需求100万倍增长,如何优化AI计算系统弥平鸿沟?

在深度学习激发的人工智能热潮下,许多创新力很强的企业的人工智能技术正逐步从研究实验走向应用与生产,在这一过程中,AI计算系统设计与优化的重要性愈发明显。 同时算法的发展对整个计算需...

技术小能手
2018/09/27
0
0
2.0 解析系列终篇 | OceanBase 2.0 到底如何做到 50% 的性能提升?

OB君:本文是 “OceanBase 2.0 技术解析系列” 的终篇。在前面的系列文章中,我们从可运维性、分布式架构、数据可用性及兼容性四个方面对OceanBase 2.0的产品新特性及其背后的技术原理进行了...

荔子liqi
2018/11/23
0
0
成为高级开发工程师必备技术能力

谁都想往高处爬,搞开发的也是一样的。你越爬的高工资越高,对吧?然而好多人都是羡慕别人的高薪,一直在羡慕嫉妒恨,却不知道自己如何才能做到像别人那样拿高薪,下面简单总结几点一个普通开...

AWeiLoveAndroid
2018/01/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

nginx学习笔记

中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。 是连接两个独立应用程序或独立系统的软件。 web请求通过中间件可以直接调用操作系统,也可以经过中间件把请求分发到多...

码农实战
今天
5
0
Spring Security 实战干货:玩转自定义登录

1. 前言 前面的关于 Spring Security 相关的文章只是一个预热。为了接下来更好的实战,如果你错过了请从 Spring Security 实战系列 开始。安全访问的第一步就是认证(Authentication),认证...

码农小胖哥
今天
9
0
JAVA 实现雪花算法生成唯一订单号工具类

import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import java.util.Calendar;/** * Default distributed primary key generator. * * <p> * Use snowflake......

huangkejie
昨天
12
0
PhotoShop 色调:RGB/CMYK 颜色模式

一·、 RGB : 三原色:红绿蓝 1.通道:通道中的红绿蓝通道分别对应的是红绿蓝三种原色(RGB)的显示范围 1.差值模式能模拟三种原色叠加之后的效果 2.添加-颜色曲线:调整图像RGB颜色----R色增强...

东方墨天
昨天
11
1
将博客搬至CSDN

将博客搬至CSDN

算法与编程之美
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部