性能优化的方法和技巧:系统

标签: 专题分析 行业动感 | 发表时间:2011-05-06 21:43 | 作者:kernelchina tiod
出处:http://www.tektalk.org

系列目录 性能优化方法和技巧

  1. 性能优化的方法和技巧:概述
  2. 性能优化的方法和技巧:代码
  3. 性能优化的方法和技巧:工具
  4. 性能优化的方法和技巧:系统

从系统层次去优化系统往往有比较明显的效果。但是,在优化之前,我们先要问一问,能否通过扩展系统来达到提高性能的目的,比如:

  • Scale up: 用更强的硬件替代当前的硬件
  • Scale out: 用更多的部件来增强系统的性能

使用更强的硬件当然和优化没有半点关系,但是如果这是一个可以接受的方案,为什么不用这个简单易行的方案哪?替换硬件的风险要比改架构,改代码的风险小多了,何乐而不为?

Scale out的方案就有一点麻烦。它要求系统本身是支持scale out,或者把系统优化成可以支持scale out。不管是哪一种选择,都不是一个简单的选择。设计一个可以scale out的系统已经超出了本文所要关注的范围,但是,scale out应该是系统优化的一个重要方向。

下面会讨论一些常见的系统优化的方法,如果还有其他没有提到的,也欢迎读者指出来。

1) Cache

  • Cache是什么?Cache保存了已经执行过的结果。
  • Cache为什么有效?一是可以避免计算的开销(比如SQL查询的开销);二是离计算单元更近,所以访 问更快(比如CPU cache)。
  • Cache的难点在哪里?一是快速匹配,这涉及到匹配算法选择(一般用哈希表),Cache容量(哈希表的容量影响查找速度);二是替换策略(一般使用LRU或者随机替换等等)。
  • Cache在哪些情况下有效?毫无疑问,时间局部性,也就是当前的结果后面会用到,如果没有时间局部性,Cache就不能提高性能,反而对性能和系统架构有害处。所以在系统设计之初,最好是审视一下数据流程,再决定是否引入Cache层。

2) Lazy computing

Lazy computing(延迟计算),简而言之,就是不要做额外的事情,特别是无用的事情。最常见的一个例子就是COW(copy on write),可以参考这个链接http://en.wikipedia.org/wiki/Copy-on-write

  • COW是什么?写时复制。也就是说fork进程时,子进程和父进程共享相同的代码段和数据段,如果没有写的动作发生,就不要为子进程分配新的数据段(通常在fork之后,会有exec,用新的代码段和数据段替换原来的代码段和数据段,所以复制父进程的数据段是没有用的)。
  • COW为什么有效?一是可以节省复制内存的时间,二是可以节省内存分配的时间(到真正需要时再分配,虽然时间不会减少,但是CPU的使用更加均匀,避免抖动)。
  • COW的难点在哪里?一是引用计数,多个指针指向同一块内存,如果没有引用计数,内存无法释放;二是 如何知道哪块内存是可以共享的?(在fork的例子里面,父进程,子进程的关系非常明确,但是在有些应用里面,需要查找能够共享的内存,查找需要花时间)

Lazy computing在哪些情况下有效?目前能想到的只有内存复制。用时分配内存算不算哪?用时分配内存不能节省时间,但是可以节省空间。静态内存对时间性能有好处;动态内存对空间性能有好处。就看目标是优化哪个性能了。

3) Read ahead

Read ahead (预读),也可以称之为pre-fetch(预取)。就是要提前准备所需要的数据,避免使用时的等待。

  • Read ahead是什么?可以参考http://en.wikipedia.org/wiki/Readahead,这个是讲文件预读的。CPU里面也有pre-fetch(CPU预取需要仔细安排,最好是能够填充流水线,所以需要多次尝试才有结果)。
  • Read ahead为什么有效?Read ahead可以减少等待内存的时间。其实相当于把多个读的动作集合成一个。这个和网络里面的buffering或者sliding window有异曲同工之妙。停-等协议是最简单的,但是效率也最低。
  • Read ahead的难点在哪里?预读多少才合适?预读窗口的大小需要根据负载,文件使用的多少等因素动态调整。预测的成功与否关系的性能。所以这并不是一个简单的优化方法。
  • Read ahead在哪些情况下有效?毫无疑问,空间局部性。没有空间局部性,read ahead就失去了用武之地。用错了,反而会降低性能。

4) Hardware assist

Hardware assist (硬件辅助),顾名思义,就是用硬件实现某些功能。常见的,比如加密,解密;正则表达式或者DFA engine,或者规则查找,分类,压缩,解压缩等等。逻辑简单,功能确定,CPU intensive的工作可以考虑用硬件来代替。

  • Hardware assist为什么有效?协处理器可以减轻CPU的工作,而且速度比CPU做要快(这个要看情况,并不是任何情况下都成立)。Hardware assist和Hardware centric的设计完全不同,不能混为一谈。在Hardware assist的设计里面,主要工作还是由软件完成;而hardware centric就是基于ASIC的设计方案,大部分工作是有硬件来完成。
  • Hardware assist的难点在哪里?一是采用同步还是异步的方式与硬件交互(通常是异步);二是如何使硬件满负荷工作,同时又避免缓冲区溢出或丢弃(这个要安排好硬件和软件的节奏,使之协调工作);还有就是硬件        访问内存的开销(尽量硬件本身所带的内存,如果有的话)。

5) Asynchronous

Asynchronous(异步)。同步,异步涉及到消息传递。一般来说,同步比较简单,性能稍低;而异步比较复杂,但是性能较高。

  • Asynchronous是什么?异步的含义就是请求和应答分离,请求和应答可以由不同的进程或线程完成。比如在 TCP协议的实现里面,如果滑动窗口是1,那么每次只能发送一个字节,然后等待应答;如果增加滑动窗口,那么一次可以发送多个字节,而无需等待前一个字节的应答。这样可以提高性能。
  • Asyncrhonous为什么有效?异步消除了等待的时间,可以更有效利用带宽。
  • Asynchronous的难点是什么?一是如何实现分布式的状态机?由于请求和应答双方是独立的,所以要避免状态之间有依赖关系,在无法消除状态之间的依赖关系时,必须使用同步消息(比如三次握手);二是应答来了之后,        如果激活原来的执行过程,使之能够继续执行。
  • Asynchronous在哪些情况下有效?很明显,状态之间不能有依赖关系,同时需要足够的带宽(或者窗口)。

6) Polling

Polling(轮询)。Polling是网络设备里面常用的一个技术,比如Linux的NAPI或者epoll。与之对应的是中断,或者是事件。

  • Polling为什么有效?Polling避免了状态切换的开销,所以有更高的性能。
  • Polling的难点是什么?如果系统里面有多种任务,如何在polling的时候,保证其他任务的执行时间?Polling 通常意味着独占,此时系统无法响应其他事件,可能会造成严重后果。
  • Polling在哪些情况下有效?凡是能用事件或中断的地方都能用polling替代,是否合理,需要结合系统的数据流程来决定。

7) Static memory pool

Static memory pool(静态内存)。如前所述,静态内存有更好的性能,但是适应性较差(特别是系统里面有多个 任务的时候),而且会有浪费(提前分配,还没用到就分配了)。

  • Static memory pool为什么有效?它可以使内存管理更加简单,避免分配和是否内存的开销,并且有利于调试内存问题。
  • Static memory pool的难点在哪里?分配多大的内存?如何避免浪费?如何实现O(1)的分配和释放?如何初始化内存?
  • Static memory pool在哪些情况下有效?一是固定大小的内存需求(通常与系统的capacity有关),内存对象的大小一致,并且要求快速的分配和释放。

系统层次的优化应该还有很多方法,能想起来的就这么多了(这部分比较难,酝酿了很久,才想起来这么一点东西^-^),读者如果有更好的方法,可以一起讨论。性能优化是关注实践的工作,任何纸上谈兵都是瞎扯,与读者共勉。

参考资料:

1:http://en.wikipedia.org/wiki/Copy_on_write

2:http://en.wikipedia.org/wiki/Readahead

3:http://en.wikipedia.org/wiki/Sliding_window

4:http://en.wikipedia.org/wiki/Asynchronous_I/O

5:http://en.wikipedia.org/wiki/Coprocessor

6:http://en.wikipedia.org/wiki/Polling_(computer_science)

7:http://en.wikipedia.org/wiki/Static_memory_allocation

8:http://en.wikipedia.org/wiki/Program_optimization

9:  http://en.wikipedia.org/wiki/Scale_out


相关 [性能优化 方法 技巧] 推荐:

性能优化的方法和技巧:系统

- tiod - 弯曲评论
从系统层次去优化系统往往有比较明显的效果. 但是,在优化之前,我们先要问一问,能否通过扩展系统来达到提高性能的目的,比如:. Scale up: 用更强的硬件替代当前的硬件. Scale out: 用更多的部件来增强系统的性能. 使用更强的硬件当然和优化没有半点关系,但是如果这是一个可以接受的方案,为什么不用这个简单易行的方案哪.

HTML性能优化技巧

- - JavaScript - Web前端 - ITeye博客
如何提升Web页面的性能,很多开发人员从多个方面来下手如JavaScript、图像优化、服务器配置,文件压缩或是调整CSS. 很显然HTML 已经达到了一个瓶颈,尽管它是开发Web 界面必备的核心语言. HTML页面的负载也是越来越重. 大多数页面平均需要40K的空间,像一些大型网站会包含数以千计的HTML 元素,页面Size会更大.

Hibernate性能优化技巧

- - SQL - 编程语言 - ITeye博客
文章分为十三个小块儿对Hibernate性能优化技巧进行总结性分析,分析如下:. 一、在处理大数据量时,会有大量的数据缓冲保存在Session的一级缓存中,这缓存大太时会严重显示性能,所以在使用Hibernate处理大数据量的,可以使用session. clear()或者session. evict(Object) 在处理过程中,清除全部的缓存或者清除某个对象.

Java程序性能优化技巧

- - CSDN博客推荐文章
如果循环次数很多,循环体内代码处理不好问题就会被放大. for(int i=0;i

Java 性能优化的五大技巧

- - ImportNew
要对你的 java 代码进行优化,需要理解 java 不同要素之间的相互作用,以及它是如何与其运行时的操作系统进行交互的. 使用下面这五个技巧和资源,开始学习如何分析和优化你的代码吧. 在我们开始之前, 你也许会担心许可的问题. Java 为 Oracle 公司所有,遵循 Oracle 的 BCL 许可,该许可证不是一个免费/开源许可证.

HBase性能优化方法总结

- - IT技术博客大学习
标签:   HBase.     本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法. 有关HBase系统配置级别的优化,这里涉及的不多,这部分可以参考: 淘宝Ken Wu同学的博客.     默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都向这一个region写数据,直到这个region足够大了才进行切分.

hashCode()方法的性能优化

- - 并发编程网 - ifeve.com
原文链接, 译文链接,原文作者: Robert Nystrom,译者:有孚. 本文主要讨论下不同的hashCode()的实现对应用程序的性能影响. hashCode()方法的主要目的就是使得一个对象能够成为hashMap的key或者存储到hashset中. 这种情况下对象还得实现equals(Object)方法,它的实现和hashCode()必须是一致的:.

java语言常用性能优化技巧

- - Java - 编程语言 - ITeye博客
java语言常用性能优化技巧介绍.     java程序常用的方法有以下几种:.     1.不用new关键词创建类的实例. 用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用. 但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法. clone()方法不会调用任何类构造函数.

Spring/Hibernate_应用性能优化的7种方法

- - 企业架构 - ITeye博客
对于大多数典型的 Spring/Hibernate 企业应用而言,其性能表现几乎完全依赖于持久层的性能. 此篇文章中将介绍如何确认应用是否受数据库约束,同时介绍七种常用的提高应用性能的速成法. 如何确认应用是否受限于数据库. 确认应用是否受限于数据库的第一步,是在开发环境中进行测试,并使用 VisualVM 进行监控.

MYSQL查询SQL语句性能优化方法

- - 数据库 - ITeye博客
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,. Sql 代码 : select id from t where num is null;.