分享
 
 
 

【原创】C++编写高性能服务器:内存分配篇

王朝c/c++·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

服务器程序有别于一般应用程序,安全与性能应被给予较高的待遇。在这里我们只讨论性能相关的问题。Apache是一款开源,安全及高性能的服务器,我经常把它放在各个档次的机器上进行测试,它总是能以较低cpu占用率和较高的吞吐量完成测试,佩服佩服啊。以Apache做为性能的参照,我从前年年底开始着手开发自己的服务器,历时两年,终于以能提供与其近似的性能(还是相差5%-10%在较差的机器上,一台P450)完成,还没取名字,暂且叫它OpenHL。

在设计上的不同处:

Apache是用C语言开发的,处理请求是一条线程(进程)完成一个请求(堵塞方式)。

OpenHL是用C++语言开发的,处理请求可以是前缀,异步及堵塞中任一方式,前缀就是Completion Port或aio了,异步是以select,poll等进行驱动。

语言方面,选用C++,除了人方便了,剩下的都是机器的麻烦了(编译累,执行累等等)。

编写自己的服务器:

在我编写完第一个版本时,性能要比Apache差不少,当时才过夏,所以测试我的AMD免去温度的影响。令人安慰的是其它几款服务器表现更差,想想人家Apache是被公认,差个10%-20%是可以被原谅的,何况我用的C++编写的,语言上也造成一定的差距,一番自我安慰后开始沾沾自喜了。

问题出现:

今年夏初,我已经将OpenHL改为第二版,在结构上做了较大的改动。我又进行了测试,测试表明改动并未产生大的影响。直到一次测试出现了不正常的现象,OpenHL的cpu占用率彪升,从原来的平均%35,上升到%60,%70...%90。停止测试后一切正常,再进行,问题仍时不时的出现。相似的是问题总是在测试20-30秒时出现。

首先能想到的是测试环境,由于夏天气温高,AMD就时有罢工。测试中Cpu会因为高温而不稳定,但不至于如此。如果Apache也有此现象就是机器的问题了,结果证明了Apache运行的很好。通过查看进程的各项指数,发现Apache的页面错误很低,而OpenHL却非常高,测试时每秒都在不停的攀升。页面错误是由于内存页未在物理内存中造成的,进程实际使用内存OpenHL要比Apache还少些。怪了怪了。

问题所在:

这个现象让我通过观察Apache源码发现,Apache是通过内存池来分配,并且每个请求都使用独立的内存池。内存池简单的分配较大内存块再切割成所需大小,这么一来一次请求实际所要从堆中分配次数也就三两次就足够了。再来瞧瞧OpenHL有多可怜,每个请求都要不停的分配大大小小的C++对象,还要不厌其烦的把它们送回家。其实不仅仅是内存分配所至,大量的分配回收带来了同步操作,同时增加了线程上下文切换,这才应该是关键。能不能学学Apache的内存池呢,答案是难,也不客观。可是应该有办法优化下我们的分配器吧,让我们看看MSDN中对此的描述,就是那篇《堆:快乐和痛苦》:Heap被如何优化了,性能有显著提升,再加上给出的优化技巧(把对象组合在一起,很明显我没有好办法把所有的字符串都拼在一起使用),就可以放心的分配内存了。

开始优化:

事实证明M$的Heap是一款很慢的分配器,慢的让你接受不了。我在网上找到几种分配器,dlmalloc,ptmalloc和hoard_malloc,后两个都是基于dlmalloc(Dong Lea)开发的。我现在用的是dlmalloc2.83,测试Heap和dlmalloc(单线程)基本不是一个档次的。我们的优化工作还没有完,单单靠分配器是不行的,不论哪款分配器在分配时仍需同步,不管它分配的再快,仍会产生很多线程切换。解决办法通过线程存储缓冲小对象,根据经验,只缓冲小于128个字节的对象,并且以16为间隔,共分8个档(在我的程序中以96做上限分6个档最好),命中率高达80%。缓冲大小为24k或32k,再高影响好象并不大。

字符串分配:我是直接使用CStringT,由于服务中需要大量使用字符串处理,我并未让它直接从分配器中分配,同样利用线程存储缓冲,方法稍有变化,这里只分32, 64, 128, 256四个档,相互独立,上限均为(8K/size)个,个人认为分前三个档效果也不错。档与档间独立的可以不相互影响,而一般对象的内存使用上,大小尺度比较散乱,并且是定长,不象字符串常需拼接操作,多分几个档可以节约开销,但档次一多就得用一个总上限来限制,这样也能根据使用情况自动调整各个档应缓冲多少。字符串的命中率高达90%。

再次测试:

这次测试基本和Apache持平,在P450上也差的很少。当然还包含了其它的优化。起码再没出现过cpu占用率彪升的情况。页面错误很少,除了启动时的,只有几百到一两千次,比Apache的还要稍微少些。

对于Heap系列函数的问题,我很不理解它在做什么,比如也HeapSize很慢,我曾建立过一个Heap,反复分配释放同样大小的内存10万次,结果是,所耗时间与内存大小成正比,16k的花了2.8秒,8k的花了1.4秒,1k的0.8-0.9秒....。而dlmalloc不管什么大小都只有50个毫秒。我的系统是Win2000 Server,AMD 2000+,内存512M。

dlmalloc 最好的分配器之一,由Dong Lea开发的,开源。

ptmalloc 实际是dlmalloc的多线程版,内置多个分配器与线程绑定,以减少同步影响。要比dlmalloc在多线中快不少,至于多少我还不知道,因为前端缓冲已经减少了绝大多数的分配操作。

hoard_malloc 实际做法和我的差不多,不过我想它没有专门对字符串优化,应该差些。我没有用它。

以后我会说说我在完成端口及重叠IO开发时的问题及解决,和一些经验。

文科学的不太好,大家将就看看吧。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有