关于多核的发展对网络游戏设计影响的一些思考
2009-01-21 11:46
741 查看
早在几年前,Herb
sutter就发表了《免费午餐已经结束,软件历史性的向并发靠拢》一文,引起了业内很大的反应,现在双核早已普及,09年应该是国内普及4核的一年。
Erlang这种老古董也因为多核的发展而逐渐热起来,网上关于普通程序员是否需要掌握多核编程技术也有很多争论,不论大家观点是否正确,至少多核相关技
术引起了开发人员的注意。
我是做游戏服务器开发的,公司的老游戏的服务器机器配置一般是带超线程的双至强cpu,逻辑上是4个cpu(关于超线程的性能提升姑且不谈),照理说,游戏服务器早就应该是多线程的设计,但是据我了解,国内大部分的游戏服务器游戏逻辑部分都是单线程的,即存在所谓主线程的说法,单线程的设计是基于以
下几个因素(以3000个玩家同时在线为列):
1:大概有20-30%的cpu被网络IO占用,网络层很容易用多线程实现
2:可通过架构上的设计剥离数据访问,IO等容易采用多线程实现的部分,剩下的占用cpu密集的操作就是所谓的主线程
3:多线程的设计会导致开发周期延长,设计变得更加复杂,可维护性降低。
3:最关键的一点:多线程带来的复杂性和bug数量,频繁的宕机回档是任何游戏都不能忍受的。
4:再来分析一下以前的双cpu服务器采用单线程的方式带来的性能损失(超线程带来的性能极为有限,暂不做讨论),粗略的来看,网络IO部分可由2个
cpu平均分摊,再抛开一些锁和缓存同步带来的开销及一些其他软件(如监控,统计),损失大概30%-40%的性能,损失的性能和稳定性及开发周期等之间
权衡,当然选择单线程的设计。
再来看如果现在启动一个新项目,对性能的考虑又该如何。首先做2个假设,1:项目周期为2年,即2年后游戏公测,或大规模内测。2:2年后服务器主流配置
为16核,低端配置8核。如果仍采用单线程的服务器设计,以16核的cpu计算,损失的性能最少会达到800%,这个时候可能有人会说,我把所有的服务器
放到一台机器上,甚至数据库也放过来,这样就能充分的利用到所有的cpu资源。不错,我承认这样基本上完全能利用cpu资源,但这不是游戏的核心内容,以
前只能支持3000个玩家,10000个激活npc的服务器,现在仍然如此。硬件在发展,玩家的体验需求也在发展,就像网络的带宽提升了100倍,我们仍
然只能看到断断续续的视频一样无法接受。说了这么多,也无非是得出一个结论:多核的发展在游戏开发当中必须引起重视。
那么,又如何利用多核资源呢?我总结了一下,大概有以下几种做法:
1:多进程设计,这是云风走的路线
2:挑战逻辑复杂性,设计良好的线程模型和数据结构
3:采用intel openmp 和 tbb 等技术
下面就以上几种设计谈谈个人看法:
多进程的设计很符合unix哲学,很kiss,难点在于进程的管理,通信,协调。优点是易于维护,调试,结构清晰。缺点是进程的管理麻烦,有一些效率损
失,最重要的一点是,多进程设计可能仍然无法有效的在多核cpu上提高效率,根据80-20法则,可能80%的cpu消耗在20%的进程内,如果根据功能
模块划分进程,即使设计良好的数据流水线,在20%的进程内也是需要做并行计算的。
第2中做法风险太大,需要多年的游戏设计经验和很好很强大的设计能力。
第3中做法比较折中,分析出占用80%cpu的那20%的代码,并行化。当然说起来比做起来容易,这种方式仍需要良好的数据结构的设计。举个例子,同时对1000个怪物做寻路操作,这种只读的操作是无需加锁很容易并行化。
结合以上几种设计,我认为最合适的做法是采用较粗粒度的进程,结合tbb等库在cpu密集操作的进程内部做并行化 是一种相对较好的设计
写的比较乱,有些地方不够严谨,以上的想法只是提供一种思路,还并未在实践中运用 :)
ps:tbb中有pipeline框架,可在进程内部方便的提供流水线机制
sutter就发表了《免费午餐已经结束,软件历史性的向并发靠拢》一文,引起了业内很大的反应,现在双核早已普及,09年应该是国内普及4核的一年。
Erlang这种老古董也因为多核的发展而逐渐热起来,网上关于普通程序员是否需要掌握多核编程技术也有很多争论,不论大家观点是否正确,至少多核相关技
术引起了开发人员的注意。
我是做游戏服务器开发的,公司的老游戏的服务器机器配置一般是带超线程的双至强cpu,逻辑上是4个cpu(关于超线程的性能提升姑且不谈),照理说,游戏服务器早就应该是多线程的设计,但是据我了解,国内大部分的游戏服务器游戏逻辑部分都是单线程的,即存在所谓主线程的说法,单线程的设计是基于以
下几个因素(以3000个玩家同时在线为列):
1:大概有20-30%的cpu被网络IO占用,网络层很容易用多线程实现
2:可通过架构上的设计剥离数据访问,IO等容易采用多线程实现的部分,剩下的占用cpu密集的操作就是所谓的主线程
3:多线程的设计会导致开发周期延长,设计变得更加复杂,可维护性降低。
3:最关键的一点:多线程带来的复杂性和bug数量,频繁的宕机回档是任何游戏都不能忍受的。
4:再来分析一下以前的双cpu服务器采用单线程的方式带来的性能损失(超线程带来的性能极为有限,暂不做讨论),粗略的来看,网络IO部分可由2个
cpu平均分摊,再抛开一些锁和缓存同步带来的开销及一些其他软件(如监控,统计),损失大概30%-40%的性能,损失的性能和稳定性及开发周期等之间
权衡,当然选择单线程的设计。
再来看如果现在启动一个新项目,对性能的考虑又该如何。首先做2个假设,1:项目周期为2年,即2年后游戏公测,或大规模内测。2:2年后服务器主流配置
为16核,低端配置8核。如果仍采用单线程的服务器设计,以16核的cpu计算,损失的性能最少会达到800%,这个时候可能有人会说,我把所有的服务器
放到一台机器上,甚至数据库也放过来,这样就能充分的利用到所有的cpu资源。不错,我承认这样基本上完全能利用cpu资源,但这不是游戏的核心内容,以
前只能支持3000个玩家,10000个激活npc的服务器,现在仍然如此。硬件在发展,玩家的体验需求也在发展,就像网络的带宽提升了100倍,我们仍
然只能看到断断续续的视频一样无法接受。说了这么多,也无非是得出一个结论:多核的发展在游戏开发当中必须引起重视。
那么,又如何利用多核资源呢?我总结了一下,大概有以下几种做法:
1:多进程设计,这是云风走的路线
2:挑战逻辑复杂性,设计良好的线程模型和数据结构
3:采用intel openmp 和 tbb 等技术
下面就以上几种设计谈谈个人看法:
多进程的设计很符合unix哲学,很kiss,难点在于进程的管理,通信,协调。优点是易于维护,调试,结构清晰。缺点是进程的管理麻烦,有一些效率损
失,最重要的一点是,多进程设计可能仍然无法有效的在多核cpu上提高效率,根据80-20法则,可能80%的cpu消耗在20%的进程内,如果根据功能
模块划分进程,即使设计良好的数据流水线,在20%的进程内也是需要做并行计算的。
第2中做法风险太大,需要多年的游戏设计经验和很好很强大的设计能力。
第3中做法比较折中,分析出占用80%cpu的那20%的代码,并行化。当然说起来比做起来容易,这种方式仍需要良好的数据结构的设计。举个例子,同时对1000个怪物做寻路操作,这种只读的操作是无需加锁很容易并行化。
结合以上几种设计,我认为最合适的做法是采用较粗粒度的进程,结合tbb等库在cpu密集操作的进程内部做并行化 是一种相对较好的设计
写的比较乱,有些地方不够严谨,以上的想法只是提供一种思路,还并未在实践中运用 :)
ps:tbb中有pipeline框架,可在进程内部方便的提供流水线机制
相关文章推荐
- 关于多核的发展对网络游戏设计影响的一些思考
- 关于多核的发展对网络游戏设计影响的一些思考
- 十问 TiDB :关于架构设计的一些思考
- 关于设计评审的一些思考
- Go游戏服务器开发的一些思考(三十):排行榜服务器设计思路
- 关于Java设计之初的一些思考
- 不只是休闲:关于体感游戏的一些思考(二) --- POV和基本场景
- 关于软件架构设计的一些思考--通用架构设计模式
- 关于设计模式的一些看法与思考
- 关于游戏架构设计的一些整理吧
- 关于推送系统设计的一些总结与思考(一)
- Go游戏服务器开发的一些思考(九):Docker桥接网络及固定IP (二)
- 关于阅读《重构,改善既有代码的设计》的一些思考
- 关于项目中下单流程HTML设计的一些思考
- 对2D游戏引擎设计的一些思考
- 关于并行计算发展的一些思考
- Go游戏服务器开发的一些思考(三十二):关于无缝世界的一些思考
- 关于类的数据成员的访问权限设计的一些思考(转)
- Go游戏服务器开发的一些思考(九):Docker桥接网络及固定IP (二)
- 关于接口设计的一些思考