AsyncPhysicsBlockMode设置为DoNoBlock会有什么潜在风险

出于优化主线程耗时的目的,现在希望物理线程耗时中,破碎物激活时构建ConnectionGraph的耗时能够不影响主线程更新耗时。

当前引擎的异步物理解算阻挡类型AsyncPhysicsBlockMode默认值为BlockOnlyPastFrames,现在希望改成DoNoBlock,物理线程不再阻塞主线程。

根据注释描述,使用DoNoBlock时,“Physics steps could be eventually be dropped if taking too much time.”

我想了解一下:

  1. 耗时超过具体多少时间的物理任务会被丢弃?
  2. 使用DoNoBlock是否还有其他可能潜在的问题?

提前感谢解惑!

你好,

Async Physics的阻塞模式设置为DoNoBlock时, 物理线程不会阻塞游戏线程, 如果物理线程运行缓慢, 之前帧未执行完成的物理任务会排队等待, 队列中任务数量目前写死的是3个, 超过的后续的物理任务就会被丢弃. 具体可以参考 FPhysicsSolverBase::AdvanceAndDispatch_External 中的处理.

我能想到的潜在问题包括, 因为丢帧, 某些事件的触发可能有小概率被漏掉, 比如碰撞 overlap, 还有就是考虑到网络同步的话, 也可能会引起服务器和客户端较大的偏差等.

好奇再问一下, 问题所说的破碎物激活时构建ConnectionGraph, 是指动态spawn了一些破碎物构建connection graph的消耗么?

运行时生成connection graph对复杂破碎物确实会比较耗时, 我们有一个选项是可以在编辑时生成, 设置是在Proximity工具上, Use as Connection Graph参考下图, 用这个工具还可以根据两个碎块接触面积来调整是否建立连接. 如果用的是Dataflow Graph创建破碎资产, 也有一个proximity节点可用, 设置是类似的.

可以先试试打开这个选项是否可以解决[Image Removed]

方便trace的时候加上这些设置然后发个文件过来么? 网盘链接也可以. 然后还想问下你们破碎资产全场景同时激活的大约几个, 每个包含的碎块数和cluster级数是?

-trace=Default, Task, AssetLoadTime, Counter -StatNamedEvents

感谢,如果在帧数较低的情况下会存在碰撞overlap小概率被漏掉的情况,那对于物理世界的整体表现影响会较大,比如角色会小概率穿过墙壁,看起来并不适合直接将Async Physics的阻塞模式改成DoNoBlock。

问题中提到的破碎物激活时构建Connection Graph,是在游戏场景中,根据Data Layer以及Streaming Distance动态生成一些破碎物时,构建Connection Graph的消耗。由于主线程Tick会等待物理线程执行完成,目前这个逻辑占用的时长会较大影响一些场景下的帧率,所以希望能够降低这个逻辑对于主线程Tick时长的影响。

目前我这边想到的方法,除了降低破碎物本身的复杂度外,就是让主线程不再等待物理线程(经过上述讨论看起来并不可靠),以及可能可以通过分帧生成的方式,让多个破碎物加载时的耗时不会都集中在某几帧(还在看如何实现中)。不知道是否还有其他的可行方案。

请问有从insight里capture下来的性能数据看下么?我这边想到的也只是优化geometry collection资产。咨询了下相关的开发,同事想看下你们的trace文件,看有没有更明确的优化方向。

方便的话如果能发个测试场景看看就更好了,感谢!

utrace文件我有一个测试关卡的,不过文件暂时发不出来,先附一张截图(后续解锁了之后我会补在此回复后面)。这个测试关卡中存在十二个箱子破碎物,通过同一个Datalayer控制加载/激活状态,箱子在游戏中设置的全部隐藏以排除渲染导致的帧数波动。录制时使用的是standalone方式启动。[Image Removed]关于测试场景,因为涉及到项目相关资产,很抱歉无法分享出来。

好的, 感谢! 可以先试试下面提到的编辑时生成Connection Graph方案~

这一点我尝试修改后,单从GenerateConnectionGraph的耗时上来说确实有明显的下降,不过整个物理线程STAT_ProcessSinglePushedData_Internal的耗时却并未下降很多,请问下这个是因为读取这个预生成的Connection Graph数据也需要花费一定的时间么?附上修改前后的utrace截图:

[Image Removed]

附上之前的utrace文件,因为后续修改过Geometry Collection资产的破碎层级复杂度,因此无法再复刻出此文件的效果了

我使用以上参数录制了一个utrace,这个场景中同时激活了十二个木箱,每个木箱目前碎块数是48,cluster级数是1​[Image Removed]

这个激活十二个木箱的文件, 我这边看STAT_ProcessSinglePushedData_Internal的耗时还好, 最长的好像也只有0.5ms.

请问还有上面截图对比的trace文件么? 就是有1.3s左右耗时的那两个, 谢谢

抱歉昨天忙别的去了。

之前的两个1.3s左右耗时的utrace文件是目前项目的流程,涉及到保密原因很抱歉不能发出来。不过我刚刚在自己的测试关卡将木箱复制粘贴到96个后,分别录制了一次没有使用Use as Connection Graph和使用Use as Connection Graph的utrace。我发现在使用Use as Connection Graph之后,测试关卡的耗时就是实打实降低了所有Generate Connection Graph的总和这么多,这与实际关卡中的表现不符。

所以我想,可能是实际关卡中我有什么其他破碎物没有改到这个数据。我准备先找相关同事帮忙把目前使用的所有破碎物进行一次统一的修改,然后再测试数据。

感谢你的耐心回复,以及再次抱歉不能将涉密文件发出来,带来的不便还请谅解。后续主关卡数据如果再有问题,我会尝试在测试关卡复现后,将相关utrace文件上传的。

好的, 后续有问题再沟通~