rimworld吧 关注:303,942贴子:5,513,855
  • 7回复贴,共1

聊聊GC、WorldPawn和卡顿

取消只看楼主收藏回复



IP属地:广东1楼2023-04-08 08:17回复
    大概有这么些内容
    1. World pawn的隐形负荷
    2. 原版的GC机制
    3. hediff与“樟脑丸”问题
    4. RuntimeGC:得与失


    IP属地:广东2楼2023-04-08 09:05
    回复
      2026-08-21 21:44:56
      广告
      不感兴趣
      开通SVIP免广告
      1. WorldPawn
      RW不像3A大作,它是模拟游戏,它的计算大量集中在CPU上。需要模拟的物体越多,游戏的速度自然变慢。
      一个常见的建议是,你卡了就少养小人和动物,减少模拟物体的数量,非常正确。
      但熟悉RuntimeGC的玩家可能会知道,游戏里还有另外一些隐形的、不在当前地图上的生物,它们也存在性能开销,使用它的清理功能可以大幅提高游戏速度。
      这些不在地图上的生物,游戏里叫WorldPawn,翻译过来叫世界地图上的生物,它们可能是:
      你自己的远行队里的成员
      袭击逃离的敌人
      撤离的友军
      派系据点的成员
      mod添加的其他成员
      之前在吧里讨论的时候,有人问,原版为什么不清除这些临时的成员,减少运算呢?


      IP属地:广东7楼2023-04-08 12:50
      回复
        2. 原版的WorldPawn:Tick和GC机制
        其实上面的问题可以拓展成三个小问题。
        先来说说第一个,这些临时的成员是否增加了运算?如果是,增加了多少?
        原版把WorldPawn分成了三类,Live(活着的)、Mothballed(封存的)、Dead(死亡的)。
        活着的WorldPawn的开销与地图上的基本一样,每一tick都会计算。
        封存时,每15000tick进行一次计算,换言之,一天4次计算。计算的项目很少,只有年龄和记录。(封存的成员可能在后续的游戏中被使用;不直接删除它们的一部分原因是故事性,一部分原因是不用一直重复生成)
        死亡的WorldPawn不会进行tick。
        不难看出,活着的WorldPawn对游戏整体的性能影响最大且持续。当你有30个这样的成员,就相当于当前地图多养了30个人。
        15000个封存的成员才相当于地图上1个人,所以这部分的影响并不大。
        死亡的成员是不会tick的,所以它们没有持续的性能开销,清理不清理没太大影响。
        死亡与存活很好理解,举个例子,一波袭击被打退后,逃跑的敌人进入存活WorldPawn列表,阵亡的敌人进入死亡列表。游戏中每过1/4天,会尝试将所有存活的WorldPawn封存(除非他们在远行队或者有健康状况禁止封存,后面细说)。
        第二个问题,原版游戏会定时清理这些成员吗?
        从上面的讨论,可以看到,如果一切正常,存活的WorldPawn都会在1/4天后被封存,而封存的成员性能影响并不大,看起来非常完美。
        阵亡的成员虽然不参与tick,但因为其他原因,比如释放内存、减少存档容量等等,原版游戏也会每1/4天尝试清除它们。清除的逻辑和RuntimeGC是非常类似的,不过没那么激进,这部分可以不细说,毕竟——阵亡的成员并不影响我们游戏的速度。
        第三个问题,如果游戏清除了这些成员,为什么我没有感觉到?
        如果我们相信原版的GC机制正常运转,为什么使用RuntimeGC还能感受到大幅度的tps提升呢?
        敏锐的人可能发现了,原版存活的成员要tick1/4天后才被封存,在这1/4天里,它们还是和地图上的人一样要正常的tick,而RuntimeGC可以提前清理掉这部分,我相信一部分性能提升确实来源于此。
        但更重要的,是我们前面讨论到的封存问题,有些情况发生,使得存活的成员无法正确的被原版机制封存。
        如果你有300个理应被封存的、但无法被封存的成员,就相当于你的地图上多养了300个人,boom。
        RuntimeGC暴力地,将大部分这些封存的成员删了。


        IP属地:广东12楼2023-04-08 13:03
        回复
          3. hediff与“樟脑丸”问题
          什么导致了本应该封存的成员不能被正常封存?
          前面说了,游戏中每过1/4天,会尝试将所有存活的WorldPawn封存(除非他们在远行队或者有健康状况禁止封存)。远行队可以理解,我们自己的成员,正常tick就行了。那么主角就是:游戏里的健康状况,标题里的hediff。
          聊原因之前我们先证明一下这种情况确实存在,而且会对性能造成影响:

          开发者选项的第五个,Debug Logging菜单中有一些可以用来调试WorldPawn的功能,我们主要用到这两个
          World Pawn List 可以打印当前所有WorldPawn的列表
          World Pawn Mothball info可以打印当前什么hediff限制了封存
          (当然最下面两个Run的命令可以直接进行GC和封存,不用等待1/4天,你可以自己试试)


          IP属地:广东16楼2023-04-08 13:36
          回复
            新开一个快速测试的存档,在Dubs Performance Analyser的World栏目中,

            可以看到全部WorldPawn的Tick开销为平均0.14ms,非常小
            打印一下WorldPawn的列表,

            存活的有17个人,大部分是派系首领。
            1/4天后,它们被封存,开销变为0.02ms


            目前为止很完美。我们打退两次moyo族的袭击,再看一下WorldPawn列表

            毫不奇怪,列表成员从17涨到了130个
            只要它们能被封存——嗯?

            Mothball info告诉我们,有85个成员,因为他们身上有MoyoBaseHediff这个健康状况,无法被封存。

            结果是WorldPawn每一个tick的耗时从0.02ms上涨到了0.621ms
            回顾一下,无法被封存的成员与地图上的成员有相同的开销,这就意味着——
            存活离开地图的moyo族其实并没有离开,它们的数量每增加一个,你的后台就多跑一个人的tick。
            想象一下,你的地图上有300个人,游戏速度会怎么样?


            IP属地:广东18楼2023-04-08 13:40
            回复
              3. “樟脑丸”
              什么?我要把moyo下了!
              你先别急。
              如果我和你说,Mincho,Miho,VE,甚至其他添加hediff的mod都可能有这个问题呢?
              如果mod里的hediff有comp,或者有复杂的stage,那么原版认为它们是需要实时计算的,
              因此哪怕拥有着这些健康状况的成员,哪怕成为WorldPawn也不能封存进“樟脑丸”里。除非在xml中写明alwaysAllowMothball和alwaysAllowMothballCached都是true。
              这是火箭人的策略,你可以在它1.4/Patches文件夹下找到MothballFix.xml,它尝试给一些hediff加上
              这两个属性。还有一些modder根据自己遇到的情况写了类似的修复, 比如https://github.com/Thekiborg/MothballFix
              但很遗憾,这是很难穷举完的。
              如果你怀疑遇到了这样的问题,可以用我们前面讲过的开发者命令,看一下是不是有大量的存活的WorldPawn,
              如果是,进一步看看是什么hediff阻止了他们被封存,然后——
              你可以给mod开发者留言,让他们加上这两个属性
              或者你把对应的hediff名字加到类似火箭人修复的xml里


              IP属地:广东22楼2023-04-08 14:08
              收起回复
                4. RuntimeGC:得与失
                毫无疑问,RuntimeGC在它诞生的年代是一个伟大的mod,哪时候甚至还没有harmony,作者要用指针来detour。
                很多年过去了,维护者还是用指针来detour。
                如前所述,原版GC正常工作的时候是不需要RuntimeGC的,用它激进地删除反而可能带来其他的问题,毕竟已经
                没什么人维护了。但从另外一个角度上讲,如果你遇到了上面的问题而且暂时解决不了,也可以激进一点全清了。
                另外,如果你要使用里面的其他功能,不清理WorldPawn,记得在mod设置中关闭这个选项,不然原版的
                GC会被完全禁用。

                (完)


                IP属地:广东24楼2023-04-08 14:25
                收起回复