性能分析总结

最近一直找项目的瓶颈,并对它做优化。做了一个多月,找到了项目的瓶颈,但无从下手去改进。虽然没有什么进展,但还是学到了不少东西。在这里对新体会的一些东西做一个记录。

项目是一个服务器端程序,同大多数服务器程序相同,它的工作主要是完成如下任务

       收消息->解码->处理消息->编码 ->发消息。

其中项目为了适应多个产商的不同消息扩展,对解码后的消息再次做了转换,转换为内部的统一的格式。相当于进行了二次解码。处理完后,组成内部发送消息格式,再转换成对应产商的消息格式,编码发送。

 

1.项目中用到了大量的STL库中的容器如vector,string,list,queue;

gcc的STL库,随版本不同,实现方式也有相当大的不同。随之的性能表现也各有不同。gcc-3.3.2中allocator默认采用内存池的方式管理内存。而在gcc-4.1.2中采用直接向系统申请内存的方式管理内存。同时提供pool_alloc(同gcc-3.3.2的默认allocator相同),mt_alloc(多线程下的内存分配器);

STL库的容器在使用时,会自动的管理内存,所以在使用时需要小心。会隐式的操作内存。向系统直接申请内存时,程序会发生上下文切换,需要频繁进入内核态,并存在加锁解锁的操作。在多线程下,频繁的申请内存会对系统的性能造成很大的影响。在必要时,需要对内存进行单独的管理。

string的使用:stl中string中遵循COW原则,采用引用计数方式来减少内存的申请复制。为了实现多线程安全的string,引用计数中采用原子锁来进行原子的加减操作。在多线程程序中也有可能影响性能。

 

2.项目中锁的使用

加锁的原则

根据要加锁区域的工作量,选择适当的锁。

spinlock 自旋锁      如果线程发现锁被别的线程占用,线程并不休眠,而是不停的轮询。适合加锁区计算量很小的任务。优点:减少了线程切换的消耗。缺点:cpu利用率低。

 

mutex   互斥锁    如果锁被占用,线程进入阻塞队列等待锁。优点:cpu利用率高。缺点:需要进行线程切换。

 

3.生产者/消费者 中消息队列

在服务器程序中大多采用这种模型来完成异步的消息处理。 生产者负责收消息,消费者来完成处理。它们通过一个消息队列来完成通信。

为了保证线程安全,消息队列通常需要加锁。加锁会造成程序的阻塞,引起线程切换的开销。可以通过双缓冲队列来减少生产者与消费者争用同一个锁的次数(原理同多线程中内存管理的方式相类似)。

 

4.线程池的模型与分配机制

leader/fellower

 

4.消息编解码的处理

服务器程序有很大一部分开销消耗在消息的编解码上 。尤其是消息的格式多变的情况下,如何高效的编码解码也是一个应该关注的问题。。

 

以上,是在分析性能过程中自己想到的,或参考别人的思路。没有经过验证,接下来的我将对这几种情况对性能的影响做比较,分析它们的适用环境。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值