找回密码
 立即注册
查看: 1316|回复: 18

[笔记] 如果用unity制作一个高性能的类工厂游戏, 我应该选择用C++/rust替换底层的运算来加速吗?

[复制链接]
发表于 2021-5-26 06:47 | 显示全部楼层 |阅读模式
前提: 类似工厂游戏这样的模拟游戏, 可以进行多线程或cache上的优化, 甚至是类似于Unity DOTS这样的一套开发模式.
发表于 2021-5-26 06:56 | 显示全部楼层
这一类游戏的性能优化的主要思路是,充分利用场景当中可变对象的相似性。
对于这类游戏,在游戏的任何一个帧循环当中,需要更新状态的对象的数量都可能远远大于状态本身和更新方法的种类。
也就是类似军队当中“整齐划一”的要求,要努力消灭单个对象的个性,强调群体的共性,将方法作用于群体对象上,而不是遍历各个对象调用其方法。
在GPU端也是类似,要充分采用instance和indirect draw,将同一个类型的对象的绘制过程合并在一个或者数个DrawCall当中,将不同个体的单独数据以某种数据结构组织在buffer当中,在一次DrawCall当中读取这些参数绘制大量对象。
动画系统也是类似,相同的对象参照同一份动画序列数据,各自保留一个指针,指向当前所处的帧。也就是动画数据只有一份,动画更新逻辑也只跑一遍,但是更新N个指针。
物理系统也要尽量选择一些群体性的判定算法,避免对于个体的迭代。
最为重要的其实是这种设计模式,而不是具体的实现语言。关键是需要摒弃商业引擎原本以单个object/actor为中心的AoS架构,改为以行为和过程为中心,单个过程处理所有适用对象的某个部分的,SoA的架构。将个体尽量表达为一组表明其状态的数据,而不是包括方法的“对象”。
发表于 2021-5-26 07:02 | 显示全部楼层
要优化类似“戴森球”这种大规模工厂类型的游戏,“用C++加速”不是靠谱的思路。
原因是:一般来说,C++和C#的运行性能区别只有几倍,说的笼统一些,1倍以上,8倍以内。如果C++写的不好还有负优化的可能。语言的性能差距没有题主想象中那么大。
如果一个算法,用C#写出来的和幻灯片一样卡,那改成C++也差不多。
算法不改进,换个语言无法解决根本问题


所以,关键是,现实中的优化问题,要找到热点(关键点),针对正确的层次进行优化。
以戴森球为例,比如地图上有10000个同样的机器播放同样的动画。优化应该先从整体考虑:
1、如果这10000个机器对应至少10000个GameObject,每帧每个机器都要执行单独的Update,那么无论Update写的多好,都还是很费CPU。
2、如果看不见的物体能够不更新,每帧能省掉好几千个Update。
3、如果这些动画都用常规的动画组件做,那肯定快不了。如果用Shader实现顶点和贴图动画,就能把任务甩给GPU,一口气解决动画渲染问题。
4、如果因为逻辑要求,每个物体不得不执行单独的逻辑,那么最终可能还是要求助于ECS,对大量物体尽可能进行批量处理。
所以,找到正确的优化重点,在正确的层次考虑优化,才能一口气把运算复杂度降下来。
至于具体是用C++实现还是C#实现,那是个细节问题。细节优化一定要放到总体优化之后再考虑,否则错过重点,劳而无获。
发表于 2021-5-26 07:03 | 显示全部楼层
unity现在不是有brust吗,先推荐DOTS里的jobs和brust,可以用于生产了
unity ecs 至今年年底都将停留在2020年的编辑器版本,5年了连个1.0都没得,下面是公告:
https://forum.unity.com/threads/notice-on-dots-compatibility-with-unity-2021-1.1091800/如果是ecs的话可以考虑下面这个框架,有多语言版本的,Entitas:
sschmid/Entitas-CSharp或者像戴森球那样在computeshader上做文章,c#现在很快的,按题主自己的思路可能是想未来移植到ue吧,不过demo都没得,我觉得没必要
发表于 2021-5-26 07:11 | 显示全部楼层
Unity有个ecs框架,可以了解一下。
戴森球计划就是用的这个ecs框架,这个技术有点难,但是也没有戴森球计划那些啥也不懂的粉丝吹得有多难,但是它的设计思维是革命性的,基本上要重新学习,习惯了面向对象设计思维就会觉得很反人类。
普通的Unity设计思维是面向对象。
使用了ecs框架的设计思维是面向数据。
具体的可以找个介绍视频看。
发表于 2021-5-26 07:18 | 显示全部楼层
其他的情况不知道,只讨论目前的一些经验.
如果是程序团队(引擎+gameplay+工具) > 20人的团队,并且打算做手游的话,我觉得要避免大量使用C#,原因有2:
    C# unity的il2cpp实现事实上和native(C++)有不小的性能差距,某些项目一些计算密集case测过有2~3倍差距.手机上要考虑发热/耗电的问题,不是一上来满帧就没问题的.C# unity的il2cpp实现有个叫做metadata的大坑,在手机上这个metadata本身会导致不小的内存消耗,更麻烦的是由此带来的性能问题(内存swap/cache miss).这个metadata基本上是你写了多少C#代码就有多少,道理上可以用editor宏来把不用的代码在编译时去掉,但是事实是意识到这一点的时候代码已经到一定量互相耦合厉害了.C# unity的il2cpp实现的GC(boehmgc)在mono内存到300M级以后的GC卡顿会比较麻烦.
rust现在的mobile工具链(考虑debug)不知道怎么样了. cpp做unity插件的话是可行的但是肯定比C#麻烦一些.
发表于 2021-5-26 07:25 | 显示全部楼层
讲真,你这么搞了半天弄不好还没DOTS快,甚至可能没有C#快
在现代,你想通过换一种语言写代码来提升性能确实越来越没多大意义了(除非某几个实在扶不上墙的)
发表于 2021-5-26 07:29 | 显示全部楼层
用dots中的job system和burst再加上gpu driven就可以了
发表于 2021-5-26 07:35 | 显示全部楼层
戴森球时代只有Compute Shader是出路
发表于 2021-5-26 07:41 | 显示全部楼层
很适合DOTS技术栈啊,配合URP,你就是性能的靓仔了。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 12:12 , Processed in 0.146709 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表