[开发者心得] 【027】【性能教室】脏标记与数据缓存

[复制链接]
874 |0
喵喵哭唧唧 发表于 2023-4-20 15:08:30 | 显示全部楼层 |阅读模式
本帖最后由 哭唧唧的细狗 于 2023-10-31 19:17 编辑

什么是脏标记,数据缓存
简单说来就是"将工作推迟到必要时进行以避免不必要的工作",避免我们做一些“无用的工作”

举个例子:
房间里有点脏,小A每小时会打扫一次房间,小B每半天打扫一次房间,晚上检查房间是否干净,效果是一样的,但是小A频繁的打扫就显得是“无用的工作”

在游戏编程里,当不需要时更新时,我们记录这些数据(数据缓存),但是不做更新,只有当符合我们逻辑设计时(脏标记设置为更新),才把这些记录的数据用于更新,以求得更好的性能表现

编辑器里该怎么做
先看看效果:


回到我们的编辑器:
我们在TS层建立了针对调用消耗较大的transform数据(位置,旋转,缩放)做了一层缓存的逻辑层。当transform属性发生更改时,我们不是直接去调用C++的修改位置接口,而是将对应的TS属性做出修改,并将该数据标脏。等待下一次tick时再统一向C++提交(玩家位置则是在每个tick内从C++更新出来)。
假如将TS调用C++的消耗定义为复杂度。假设有某一逻辑帧内有m个对象需要更新transfrom数据,平均每个对象调用transform相关接口 n次。
那么未在ts缓存方案的复杂度为Om*n
缓存过后的方案为Om+1

简单来说,我们建立了一个用于是否更新表现的逻辑层
* 如果对象的逻辑位置在更新范围内,则设置真实对象的位置变动及其它逻辑更新
* 否则只更新逻辑层的位置变动

image.png
(图1 MiddleComponent即为最小Demo中的逻辑层,_isLocDirty是脏标记,_location是数据缓存)

image.png
(图2 在设置位置时不是直接去调用GameObject.worldLocation,而是修改缓存数据,并且标脏)

image.png
(图3 ,在tick中更新C++的位置,这样后面合批提交加入后也方便快速接入)

其它细节

更新位置旋转缩放这些

* 如果是在单机游戏里,则在客户端设置即可

* 如果是在多人游戏里,则需要将对应代码逻辑在服务器上


最小Demo:

RectangleTest.rar (112.61 KB, 下载次数: 22)

回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表