简述
总结ue4中性能优化工具合集,之前转过一篇llm内存统计工具,非常详细,这里会总结全面,包括了cpu/gpu/内存/功耗/包体/代码稳定的各类工具,方便筛选使用
对于每一帧来说,执行顺序依次为:game thread → draw thread → gpu thread
game thread 首先会对整个游戏世界进行逻辑层面的计算与模拟(e.g.spawn 多少个新的 actor、每个 actor 在这一帧位于何处、角色移动、动画状态等等),所有这些信息会被输送到 draw thread;
draw thread(也叫 rendering thread) 会根据这些信息,剔除(culling)掉不需要显示的部分(e.g. 处于屏幕外的物体),接着创建一个列表,其中包含了渲染每个物体必备的关键信息(e.g. 如何被着色、映射哪些纹理等等),再将这个列表输送给 gpu thread;
gpu thread 在获取了这个列表之后,会计算出每个像素最终需要如何被渲染在屏幕上,形成这一帧的画面。
cpu
game thread 造成的开销,可以使用stat game显示 tick 的耗时情况 ;dumpticks:可将所有正在 tick 的 actor 打印到 log 中
unreal insight
unreal insight在 unreal engine 4.24.3版本中开始支持移动平台性能数据录取。数据直接写入文件,gui工具采集结束后离线解析数据文件。(平时使用较多)
优势:可长时间录制数据,数据在时间轴上以进程调度的形式展示,比较容易分析game、renderthread与workerthread的调度情况,从整体上结合时间连贯性对cpu瓶颈进行初步的定位。也可用于分析有规律的卡顿掉帧的情况。
劣势:所记录的调用堆栈较浅(可手动打点),较难定位到具体出问题的代码,人工分析需要时间与经验
unreal profiler
(平时使用较多)unreal engine 中的 profiler则是分析cpu端性能情况的一个老工具,与unreal insights相比它缺少了线程间调度情况的数据,优点在于其记录的调用堆栈深度较深,可与insights结合使用 ue4引擎窗口中菜单developertools下sessionfrontend界面即为profiler所在的窗口 可通过两种方法抓取数据:
启动程序时增加参数:-messaging
游戏中使用命令: stat startfile, stat stopfile
/sdcard/ue4game/yourproject/ue4commandline.txt
../../../yourproject/yourproject.uproject -messaging
# 数据存放于
/sdcard/ue4game/fpsdemo/fpsdemo/saved/profiling/unrealstats
simpleperf
simpleperf可录制很深的cpu调用堆栈,可用于详细分析问题时间内的cpu代码执行情况,其将数据聚合,输出类似于instrument timeprofiler的形式,可以看到不同函数在一段时间内的贡献、占比情况,及调用次数,方便对其进行更有针对性的优化。但这种聚合模式没有单帧的概念,主要用于宏观统计。因此可以与profiler、insights等工具结合使用。建议使用test包进行数据分析,避免development版本额外代码所造成的性能压力影响真实数据
android studio
使用android studio的 profileapk 功能,即可较为自动的生成性能数据
perfetto
perfetto可以拿到simpleperf、systrace等数据
可用于分析app、系统整体cpu调度,渲染节奏等问题
xcode timeprofiler
xcode timeprofiler 与simpleperf原理相同的cpu性能分析工具,功能强大
best practice
粗粒度工具:framepro、unrealinsight 用于开发期ci暴漏明显问题
发现问题后,使用细粒度工具进行深度分析:simpleperf、streamline、timeprofiler
建议使用test包,排除cache、冗余代码、profiler本身对性能的影响
尝试:离线计算、parallelfor、异步化、soa化等方案
并使用cachesim、streamline进行 cache miss 分析,压榨出最后的水分
gpu
如果是在pc平台上可以使用profilegpu命令或者使用快捷键ctrl+shift+,影响gpu瓶颈最主要的是basepass和prepass
现代mobile gpu通常使用 tbr、tbdr 硬件架构
在有限的功耗下提供尽可能多的性能空间
除了控制 运算负载、动态分支、全精度运算 等天然gpu不友好的指标之外
mobile gpu因其on-chip memory较小的原因
需要严格控制寄存器数量,避免register spill产生额外io带宽
adreno gpu
adreno gpu
使用snapdragon profiler进行counter数据抓取 提供python脚本进行counter数据汇总与分类
mali gpu
android gpu inspector (agi)
系统性能分析
执行系统级跟踪和分析,以深入了解游戏和系统服务使用的资源,例如 gpu、cpu、内存、电池和 gpu 计数器。支持 qualcomm® adrenotm、arm® malitm 和 imagination® powervrtm gpu
帧性能分析
从单个应用帧捕获跟踪记录,然后对游戏的 gpu 使用情况执行深入分析。其中包括对 vulkan 和 opengl es api 调用进行更深入的介绍和分析
内存
android、ios内存管理核心:
- 分页(paging)
- 内存映射(memory mapping)
cpu & gpu 公用一套内存硬件(gpu有少量onchip memory)
当内存不足时触发分页(page out)释放内存:触发 内存压缩; 删除clean page; 当剩余内存低于阈值,系统将开始杀进程
堆内存分析
android studio
android studio 支持 native(c++) 堆内存分配的分析工作
perfetto组件可使用heapperfd进行native内存分析工作
loliprofiler
loliprofiler支持整合至 ue、unity 引擎分析 native(c++)内存
ue5 memory insights
unity mono 内存
mono虚拟机(il2cpp)提供内存快照接口
unitymemperf用c++&qt完美还原了unity il2cpp内存工具perfassist的体验,无需unity、无需sdk,连接usb拉起app即可抓取托管内存快照,进行内存分析、快照diff
memreport
提供 ue4 memreport 数据解析、diff与可视化功能:(经常使用)
rhi memory
可针对性的对 ue vulkan、gl、metal rhi层内存申请接口结合 frhiresource 的debugname
实现一套数据dump机制,以链接 rhi 内存与 ue rhi资源,深入分析rhi内存
xcode allocations
类似 simpleperf 在 ios 可查看堆内存分配数据的工具
ios memory deep dive
功耗
手机硬件集成度高,重度手游发热明显,发热与功耗的关系越来越受到开发者的重视
功耗统计难点:
- 硬件集成度高,被动散热上限低
- 难以测量单模块功耗
- 静态、动态功耗叠加
- 能耗和利用率、频率呈线性关系,和电压呈二次关系
综合导致:功耗数据获取难度大,功耗数据体现非线性,数据分析难度也很大
优化建议:均衡cpu利用率;多线程使用;空间换时间;注意屏幕耗电;实时查询响应能耗发热;与硬件厂商合作
硬件方案
电流计
设备充满电(100%),将电流计与充电头连接。
在系统的蓝牙管理面板中查找设备,配对连接并且获取其mac地址记下。
软件方案
perfdog
支持基于驱动上报的功耗数据获取, ios直接解析了xcode energy的数据
android 的 snapdragon profiler
snapdragon profiler
使用实时指标识别潜在问题区域,从 150 多个硬件性能计数器中进行选择
分析跨 cpu、gpu 和 dsp* 的系统、图形和 ml 工作负载
使用 snapshot 捕获捕获和调试图形工作负载,从而实现更深入的帧和着色器分析
对任何 directx、vulkan、opencl 和 opengl es 工作负载进行详细分析
ios 的 instruments
instruments 是 xcode 的一个工具集,为我们提供了强大的程序性能分析及测试能力。可以进行cpu 性能测试、图形性能测试、内存性能测试等
包体
包体的大小、首包资源的大小对于玩家有较大影响
尽可能减少包体大小,也是开发者需要关注的重点问题
sizemap
sizemap介绍,可以将本地的pak包加载, sizemap以treemap图的形式将资源分类,我们可以点击任意分类进入更深的层级来分析数据
unreal pakviewer
custom built profiler with ci
asset registry 中包含资源的 meta 信息(assetregistrysearchable),可在cook & package 结束后使用 commandlet 分析此信息
代码崩溃 & 稳定性
可通过addr2line翻译崩溃符号至具体代码行号
# android-ndk-r21d\toolchains\aarch64-linux-android-4.9\prebuilt\windows-x86_64\bin\aarch64-linux-android-addr2line.exe
addr2line.exe -f -c -e path/to/libue4.so 0x009988ff
address santizer
android、ios平台原生支持 asan,ue也已整合至引擎中
测试asan包,提前发现内存越界、use-after-free等常见内存问题
安卓使用asan检查ue4内存问题
stompallocator
windows平台也支持asan,不行的是至少4.27版本的引擎仍旧无法正常使用asan功能
可使用替代品,ue内部的 stomp allocator(会占用巨量虚拟内存(60g+))
https://pzurita.wordpress.com/2015/06/29/memory-stomp-allocator-for-unreal-engine-4/
通过page可以设置read、write保护的特性,在每次申请内存时,使用page读写保护来保护内存区域
当越界读写时,就会触发保护,从而崩溃在问题出现的第一现场
vulkan
vulkan rhi在较新的移动设备中已全面支持
其rhi性能、驱动内存占用,可玩性、以及可优化性 远超 opengl rhi
包含command的trace工具,发现崩溃问题时,可通过trace工具记录完整command数据
发表评论