关于memory:TMP耗时较高的优化问题

10次阅读

共计 2680 个字符,预计需要花费 7 分钟才能阅读完成。

1)TMP 耗时较高的优化问题
​2)Unity 重载 Object 后,如何断定物体是否为空
3)SRP Batch 在增加 unity_SpecCube 后的问题
4)堆内存会持续上升,如何用 UWA 报告来剖析


这是第 326 篇 UWA 技术常识分享的推送,精选了 UWA 社区的热门话题,涵盖了 UWA 问答、社区帖子等技术知识点,助力大家更全面地把握和学习。

UWA 社区主页:community.uwa4d.com
UWA QQ 群:465082844

TextMeshPro

Q:咱们我的项目中 UGUI 的 Canvas.SendWillRenderCanvases 耗时高时常常看到子节点 TMP.GenerateText 和 TMP Parse Text 耗时高。根本能定位到是角色对话字母跳字的时候,然而这是硬需要不好改。大佬们有没有什么思路优化一下?

A1:倡议独自给这块开 Canvas。

感激欧月松 @UWA 问答社区提供了答复

A2:角色对话时字幕上一个一个字蹦出来的确是比拟常见的需要了,都是在一个 Text 组件里变动,而且字越多顶点数就越高,耗时就比拟可观了。

我想到的一个思路还是改用动态字体图集。
可参考:https://answer.uwa4d.com/question/63e30f3b0638540599016732

我之前也遇到这个问题,所以做了下试验:
在一个 Text 组件里用代码管制间断输入 3000 个中文字符集中各不相同的文字。在 Profiler 中察看到:

  1. 当应用动静字体时,每输入一个字符都会在相应的 TMP 动静图集纹理资源中新画入一个字符,在 Unity 2021、TMP 3.0.6 版本环境下,输入到最初几个字符时,Canvas.SendWillRenderCanvases 耗时来到 24ms 左右。
  2. 过后在用动态字体时,同样的输出形式和环境下,输入到最初几个字符时,Canvas.SendWillRenderCanvases 耗时升高到 14ms 左右。

在还有一些补充测试中,耗时差距在真机上被进一步放大;而且在一些较低的稳固版本的 Unity 和 TMP 环境中试验后果也差不多。这里就不一一列进去了。总之,足以阐明应用动态字体计划在耗时层面也是具备优越性的。

感激 Faust@UWA 问答社区提供了答复

Script

Q:Unity 重载 Object 的 == 后,如何真的断定物体是否为空?

Unity 中还找不到除了 Try Catch 外,去辨别 Destroyed 的物体和 null 的区别。一些资源追踪操作,能够查看 Destroyed 的物体,比方:取得 Destroyed 物体的 InstanceID,去辨认到底具体出问题的货色是什么。然而如果应用真 null 的物体调用这类接口,就会出现异常。

当初想找一个,不触发异样的洁净办法,断定一个物体是被捣毁,还是真 null。

A:简略的写法:
真 null 的判断:(go as object) == null;
如果不是真 null,能够持续判断是不是 Destroyed:(go as UnityEngine.Object) == null。

该答复由 UWA 提供

Rendering

Q:SRP Batch 在增加 unity_SpecCube 相干参数后,呈现 “builtin property offset in cbuffer overlap other stages”。

其实是之前问题的具体情况。在反对 SRP Batch 的 Shader 增加反射探针相干参数后:
如果把探针参数放在 UnityPerDraw 外面,测试多种参数程序,都会呈现 “builtin property offset in cbuffer overlap other stages” 问题;
然而放在 UnityPerDraw 外,又会呈现提醒要求把相干参数放进外面去。

当初集体想法是,这些参数应该放进 UnityPerDraw 内,然而具体程序有问题。不晓得有没有胜利植入测试的例子。或者是对源码有了解的兄弟能够给出一个可行的程序。

具体呈现问题的版本是 2020.3.16f1。

我的项目现有问题倒是通过将相干参数放在 CBuffer 外,外加强制裁减变体,在测试到的环境中解决了。然而还是心愿可能解决这个深层次的坑。

A:明天也遇到这个问题了,看了下源码,这些 Built-in Feature,例如反射探针或者 Motion Vector,Unity 是有一个 Feature List 来解决的,每当你开启一个 Feature,会在 UnityPerDraw 调配一个 Block,而后你新退出的参数必须跟这个 Block 大小匹配。

我的问题是 Motion Vector 只用到了一个矩阵和一个 float4,然而 Unity 给调配的大小就是两个矩阵 + 一个 float4,所以如果要不影响合批,就得这么申明。

你的状况感觉能够增加到 probeVolume 这个 Feature 的 Block 里,Catlike 教程里也有提过,测了下程序不要紧,大小统一就行,3 个 float4 和一个矩阵。

感激 xltqM7stGjuG@UWA 问答社区提供了答复

Memory

Q:大佬们问一下,咱们我的项目的堆内存会持续上升到 400 多 MB,这个值太高了,而 UWA 报告中无论是平均分配值乘以帧数还是泄露剖析中的驻留量尽管也很高,然而离 400MB 还有一些差值。到这里不晓得怎么持续剖析了,有没有好的倡议?

A:2022 年底帮一个我的项目解决了内存始终涨的问题,起因也是内存碎片。刚开始认为是资源出的问题,始终用 Memory Profiler 在定位问题,只能看到 Empty Heap Space 始终在涨,到最初发现这个工具找不到起因,然而大略确定了是内存碎片太多。最初通过 GC Allocated 的变动定位了局部性能。

在这个过程中发现了 Profiler 里的波形和数值有时候是对不上的,明明有一个很大的波峰,但数据显示基本不对,这时通过这条波峰是定位不到性能代码的。

总结几个容易呈现碎片的关键字:

  • byte[]
  • MemoryStream
  • ReadPixels
  • DeflateStream

解决办法:大部分状况能用对象池解决。

感激李伟 @UWA 问答社区提供了答复

封面图来源于网络


明天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题兴许都只是冰山一角,咱们早已在 UWA 问答网站上筹备了更多的技术话题等你一起来摸索和分享。欢送酷爱提高的你退出,兴许你的办法恰能解他人的当务之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官网技术博客:blog.uwa4d.com
官网问答社区:answer.uwa4d.com
UWA 学堂:edu.uwa4d.com
官网技术 QQ 群:465082844

正文完
 0