

前言:
为了帮助项目建立稳定可控的性能管线,及时发现性能问题,快速定位并优化,PerfDog团队开发了深度分析功能。从CPU的调度和使用,到线程的运行状态,再到调用堆栈,以及渲染截图,PerfDog都可以准确获取,让分析更加全面。配合数据管理平台,在日常版本中有性能问题时,可以快速版本对比,也可以用Web端多人协作分析,定位到函数或模块级别,及时优化和修复,保障项目的性能稳定可控。目前功能已在内测中。
快速体验,使用指南
Android平台:
https://perfdog.qq.com/article_detail?id=10214&issue_id=0&plat_id=1
iOS平台:
https://perfdog.qq.com/article_detail?id=10213&issue_id=0&plat_id=1
核心功能:
从CPU调度,到线程状态及调用栈,再到渲染截图,让分析一步到位。
快速定位卡顿帧,直击代码级别;高效计算stat/profile数据,低帧原因一目了然。
提供多种语言接口便于二次开发,以及集成自动化性能分析管线。
高效数据管理平台,方便对比分析,更快定位原因。
支持UE/Untiy双引擎,支持Android及iOS双系统。
关键stat/profile数据分析
1) 实时stat/profile数据查看,及时发现低帧或异常的stat/profile。
也可以在“添加事件”中,搜索添加stat/profile事件到OverView中,进行实时查看需要重点关注的事件。
可以右键选择Max FrameTime,直接跳转到最大的FrameTime帧进行分析。当然
也可以选择跳转到Max CollectGarbageInternal或者其他任意添加的事件进行分析。
可以右键选择Save,能保存数据到本地
2)Stat/profile数据统计分析,调用栈以及被调用栈。详细统计了一段时间或者单帧中stat/profile的次数、总耗时、平均时间、最大及最小耗时。支持搜索及排序,快速找到热点stat/profile。
3)数据分析更加便捷。通过鼠标悬浮、单击、框选、右键等操作快速得出统计值,减少线下二次计算时间,将精力聚焦到分析问题上。快速计算选定帧中各个stat/profile与均值的差值,如下图所示:
CPU调度
2)分析主要线程运行状态、同步以及耗时。例如,分析核心线程之间的同步是否正常,是否存在过长的等待。以及线程状态是否正常,是否在Running与Runnable或Sleep之间频繁切换。
线程状态及stat/profile数据
1)深入分析堆栈及耗时,快速分析高耗时或异常stat/profile。
2)每个线程的状态,并且与线程所执行的stat/profile对齐。方便查看多线程之间的执行关系,以及执行状态是否合理。例如,核心线程是否因为等待其他线程造成卡顿。配合stat/profile分析,是否可以分帧或者合理的并行执行。
渲染截图
1)超低消耗的定时截图,快速定位瓶颈原因
2)自动配比到当前分析帧,方便分析当前的操作和渲染
数据管理
数据持久化存储,便于性能对比分析和优化案例积累。团队共享数据,高效合作定位问题及跟进优化。
web端分析
Web端同样具备数据统计分析功能,方便团队协作分析。
模式选择
可根据被测应用具体情况,选择合适的模式进行深度性能分析。
Systrace:基于Android/iOS的事件跟踪机制,主要适用于非游戏、UE4.23版本之前开发的游戏。性能影响仅为Android/iOS系统的分析功能(例如systrace/ instruments)的30%。
Unreal/Unity:适合于Unreal/ Unity引擎开发的应用或游戏,基于引擎性能采集机制,将数据处理与主要线程脱离,从而将性能影响降到最低,相比较UE Insight/Unity Profile性能影响在3%以内,可以更加精准的分析性能。
案例分享:
发现问题:
在性能测试过程发现有明显顿卡,然后利用深度分析功能进行分析,重现顿卡的场景或实时查看每帧的FrameTime,发现有明显的尖刺,即可进行分析,如下图所示:
框选包含FrameTime异常的一段,可以统计各项stat/profile的平均及最大值:
可以很方便的看到,FrameTime平均值为30ms,但最大为239.16ms,只有不到5帧,为明显的顿卡帧。此时可以右键直接跳转Max FrameTime的帧进行分析。
CPU各核使用:
先查看该顿卡帧发生时的CPU使用情况,如下图所示:
可以非常明显地看到RHIThread占用了很大比重的CPU,而GameThread和RenderThread几乎没有运行。也可以双击线程名,只凸显出该线程的占用,可以更直观的追踪该线程的运行情况,如下图所示:
线程分析:
此时基本判断是因为RHIThread耗时过长,并且导致了GameThread和RenderThread被挂起,进而造成了严重顿卡。可以进一步分析该帧的火焰图进行分析。
先来查看GameThread,发现Game thread idle time耗时达到210.47ms
RenderThread中CPU Stall – WaitUntilTasksComplete耗时219.13ms
而RHIThread中Shader Link time耗时222.92ms。
Stat/profile Detail:
此时可以明确判断出是因为Shader编译时间过长,导致RHIThread耗时过大,GameThread和RenderThread等待过长,造成明显顿卡。也可以选中Shader link time右键点击Detail,查看该帧详细的stat/profile,可以看到在当前帧中Shader link time耗时达到217.36ms,如下图所示:
具体是那个Shader,可以参考Callers(这里为Translucency相关)增加针对性的stat/profile或log,也可以借助截图进行判断。
渲染截图:
卡顿发生在51.34s左右,可以查看相邻时间的截图。为尽量减少对游戏性能的影响,PerfDog设定2s截图一次。
双击放大51s和53s的截图,如下所示:
对比发生顿卡前后两张截图,可以快速判断是因为花瓣相关的Shader编译导致顿卡。可以预编译进行优化,而不是在运行时再进行编译,避免因Shader编译导致顿卡。
总结:
在OverView中实时查看FrameTime或者其他需要检测的stat/profile,当发现异常时,直接跳转到异常帧,配合CPU Scheduling、线程状态、火焰图及详细stat/profile统计,并利用截图可以快速分析具体导致顿卡的原因,从而进行针对性的优化。