UDN
Search public documentation:

PerformanceDebuggingCH
English Translation
日本語訳
한국어

Interested in the Unreal Engine?
Visit the Unreal Technology site.

Looking for jobs and company info?
Check out the Epic games site.

Questions about support via UDN?
Contact the UDN Staff

性能调试

概述: 如何调试虚幻引擎中的帧频率问题和其它停顿问题。

文档变更记录: 由Mike Fricker创建并维护。

游戏性能概述

以下部分将帮助您学习很多用于查找性能问题、瓶颈及停顿障碍的有用工具。

通常,首先需要确定帧是否受到CPU或GPU性能的限制,然后使用适当的工具跟踪限定问题的范围。

如果CPU运行速度很慢,那么有很多命令和调试工具可以帮助您处理这个问题。有时候,可能只是由于actors的数量太多的或者“移动的部分”数量太多而导致帧频率较慢,或者可能是因为一个脱离的AI类每帧正在激活成千次的光线投射。只要耐心一点,您就可以跟踪发现这些性能问题并准确地定位到单独的关卡actor上!

对于GPU性能,您或许需要使用PIX来分析描画事件或着色器性能、以及游戏中的可视化模式和HUD统计数据。有时候,这些问题可能会最终跟踪到内容布局或光照属性上。

无论哪种情况,您都可能遇到持续的较慢帧频率问题或停顿问题(较大的帧时间顿卡)。对于持续的较慢的帧频率来说,单独帧的捕获工具(比如TRACE 命令)和采样优化器(VTune等)可能是非常有用的。对于停顿来说,您将需要使用StatsViewer工具通过函数调用图来分析以前的帧。

注意,尽管大部分Unreal工具可以在多个平台上工作,但是一般游戏机平台的调试工具和PC平台是不同的。

调试性能:步骤

准备调试:

  1. 首先,确保当您正在运行游戏时,打开STAT UNIT命令。
  2. 配置您的构建环境。当测量性能时请使用ShippingDebugConsole (LTCG)版本;当调试性能时请使用Release(发布)版本。
  3. 确保 关闭任何日志垃圾或者干扰性能结果的调试代码。
  4. 关闭垃圾回收验证,因为它将会导致帧停顿。
  5. Final Release(最终发行版本)模式下编译脚本。
  6. 禁用VSync,以便您可以识别瓶颈,即使在较快的帧频率上。

分离瓶颈类型:

  • 使用STAT UNIT来决定为什么帧频率较慢。
    • 您应该可以分辨出是CPU问题还是GPU问题。

CPU - 找到运行较慢的C++或UnrealScript代码:

  • 打开 STAT SLOW,来帮助辨别CPU上的帧停顿。
  • 使用平台CPU取样工具来捕获C++代码的分析数据。
  • 使用统计数据查看器来获得UnrealScript调用函数和基于状态的时间数据以便使用。
    • 这对于追踪基本性能的bug是非常有用的。
  • 使用脚本分析 来查找UnrealScript的热点区。

GPU -决定了导致较低渲染性能的原因:

关于解决一般的虚幻引擎性能问题的指南:

请确保优化了关卡内容和资源:

  • 通常,性能问题需要通过改变或优化关卡及资源来解决。
  • 请参照内容优化部分来学习所提供的有用工具。

性能参考指南

显示 帧/线程/GPU事件(STAT UNIT)

使用 STAT UNIT 命令判断帧时间瓶颈出现的地方。 STAT UNIT 将启动一个屏幕上的HUD来显示帧时间、游戏线程事件、渲染线程(描画)时间和GPU时间(如果可能)。这是跟踪性能问题的第一步也是非常重要的一步 -- 您应该总是打开这个命令。

同时,您可以使用 STAT FPS 命令来在屏幕上显示帧频率和帧时间。

编译配置

当测试性能时,您应该使用 Release(发布)ShippingDebugConsole (LTCG) 编译配置。*ShippingDebugConsole* 提供的性能数值接近于发行的游戏所提供的数值,但是某些性能测量及调试功能(比如统计数据捕获)可能是不可用的。通过进行一些小的调整, Release 版本可以满足性能和内存测试需求,只要您 分别地 查看数值结果即可。

注意,如果您正在使用 Release 版本进行测试,那么您应该关闭大量的日志记录,可以使用命令禁用日志记录或者使用 #ifdef在编译时把日志记录功能注释掉。比如, "suppress AILog" 命令可以关闭针对游戏的所有AI日志记录,这些日志将会减慢C++和脚本程序的运行速度。

关闭垃圾回收确认功能

当处理性能问题时,您应该总是关闭 GC Verification ,否则在 Release(发布) 版本中将会看到大量的停顿现象,每次大约停顿30秒左右。您可以使用以下方法之一来关闭垃圾回收确认功能:

  • UnObjGC.cpp 文件中, 确保 VERIFY_DISREGARD_GC_ASSUMPTIONS0传入 *-NoVerifyGC 命令行参数。

以 Final Release(最终发布版本)模式编译脚本

当启用日志功能和断言功能时,UnrealScript的性能会有很大的差别。获得接近于发行版本的游戏性能的最简单方法是以 Final Release(最终发布) 模式编译脚本,该模式可以自动地从编译后的字节码中剥离性能消耗较高的函数调用。您可以通过以下几种方法之一来编译 Final Release(最终发布) 版本的脚本:

  • 虚幻前端, 选择 Cooking(烘焙) 标签并启用 "Cook Final Release Scripts(烘焙最终发布版本的脚本)" 复选框。现在,当您运行烘焙器或通过UFE启动游戏时,将会编译并使用 Final Release(最终发布) 版本的脚本。
  • make 命令行开关中传入 -Final_Release 命令行参数。

禁用VSync

要想获得最好的效果,您需要关闭 VSync (在呈现帧之前等待垂直的折回)。否则,帧时间将会被填充到游戏的刷新频率上,这会导致更难获得精确的图像。要想关闭 VSync :

使用STAT SLOW

您可以使用 STAT SLOW 命令帮助您找到性能波动问题。它可以通过报告运行时间长于一帧中特定时间段(默认10毫秒)的任何循环统计数据来帮助您逐步定位帧停顿发生的位置。运行速度较慢的统计数据将会在HUD上显示一段时间,从而可以更加容易地把性能波动和屏幕上的游戏行为联系到一起。

要想使用该命令,可以在控制台中输入 STAT SLOW 和用于说明阈值的可选参数,该参数以秒为单位(所以10ms也就是0.01秒),也可以输入代表一旦波动停顿发生渲染统计数据所持续的时间的参数。默认值是 10秒。

实例: STAT SLOW 0.01 10

这将会渲染在过去的10秒内所有运行时间超过10毫秒的循环统计数据。

分析CPU

当您分析出您的帧瓶颈是CPU性能问题时,下一步应该是决定那些时间是C++代码中的哪部分消耗的。另外,您或许想查找类似于Load-Hit-Stores或缓存丢失的隐藏的性能消耗。

大多数平台都有功能强大的CPU采样工具,它们提供了详细的代码标准,甚至提供了使用从活动会话捕获的数据组成的C++代码调用图表。比如,在Windows平台上,您或许使用 Intel VTune 来捕获一个较短时间段内的数据从而分析出热点区。游戏控制台平台也提供了类似的工具,通常包含在开发工具链中。

如果您想熟悉这些应用程序,那么就在开发过程中大量的使用它们把!

注意,在某些游戏控制台上,Unreal有一些工具用于帮助执行单独一帧的CPU/GPU采样获取。您可以输入 TRACE GAME 来启动一个CPU踪迹,或者 输入 TRACE RENDER 来捕获GPU数据。

大多数CPU分析器支持捕获较短时间间隔内的采样数据 和/或 调用图表数据 的功能。这对于调试关于具有持续的低帧频率的性能问题是非常有用的。_Sampling captures(采样捕获)_ 通常会为您提供C++代码中的函数调用热点区。这有时候是有用的,但大多数时候您会发现 Call Graph capture(调用函数图表捕获) 是更加有用的!

Call Graph capture(调用函数图标捕获) 通常会有更多的捕获时间消耗,但是它提供了关于热点区的函数的 调用者 的详细信息。这通常可视直接引导你查出问题的根源!即使在许多 物体/actors正在调用显示为运行速度较慢一个单独函数的情况,如果您很幸运,那么调用函数图表将会引导您到特定的actor类别名称或导致这个原因的其它形式的暗示。

有时候调用函数图表将简单地显示 UnrealScript 所占用的时间(调用 ProcessEventCallFunction 等),在这种情况下您需要运行一个StatsViewer(统计数据查看器)Script Profiling(脚本分析) 来捕获这些调用函数的消耗。

当处理帧 停顿 时,由于相对较低的采样频率,CPU分析器可能有时候是不适用的。如果停顿在游戏中很容易再现,一个很好的策略是当捕获一个较短的CPU采样会话时,尽量经常地启动那个停顿(理想地每帧很多次)。如果那个停顿是很难捕捉的,你将需要使用StatsViewer(统计数据查看器) 中捕获的数据,它提供了在很多帧上的历史调用函数图表。

使用StatsViewer(统计数据查看器)分析代码

您可以使用 StatsViewer(统计数据查看器) 来帮助您跟踪CPU性能问题。它也可以用作为UnrealScript代码的详细分析工具。

StatsViewer(统计数据查看器) 将沿着图形化的时间轴显示所有的 UnrealScript函数调用游戏统计数据 (数值计数器、循环计时器等),您可以在时间轴排序和查看数据,和您在PIX中的操作类似。更加重要的是,它可以为您显示一个范围内的循环统计数据和脚本函数组成的漂亮的 *层次化的函数调用图*。这个图表可以使您迅速查找到任何指定帧中“那些函数较慢”。(只要在图表窗口中双击该帧即可)

准备:

  • 请确保您正在使用的版本中的 STATS 定义为 1 (UnBuild.h)。
    • 在Debug(调试) 和 Release(发布)版本中这项是默认启用的。
  • 要想分析脚本代码,也要确保 STATS_SLOW 定义为 1 (UnStats.h)。
    • 这将会减慢分析的速度,但是提供了所有UnrealScript调用函数的详细调用图。

要想把统计数据捕获到磁盘上(推荐):

  • 在控制台中输入 "STAT StartFile" 来开始捕获数据到磁盘中。
  • 当完成时,输入 "STAT StopFile" 来停止记录和完成统计数据文件。
  • 要想在应用程序启动时立即捕获统计数据,需要传入 "-StartStatsFile" 参数。
  • 在游戏机平台上,请确保传入 -DisableHDDCache 命令行选项!
    • 这将会关闭贴图mips到HDD的缓存(它与统计数据文件写操作争夺缓存)。
  • 统计数据文件将会输出到 \UnrealEngine3\\Profiling\文件夹中。
    • 在控制台游戏平台上,将会通过UnrealConsole把统计数据自动地转换到PC上。
  • 运行StatsViewer并加载文件(比如 -07.15-18.58.ustats)。

要想从运行的游戏中捕获活动的统计数据:

  • 加载游戏
  • 使用 连接到IP 把StatsViewer(统计数据查看器)和Xenon会话连接到一起。
    • 在Xenon上,使用Xenon的"Title IP Address",而不是"Debug Channel IP Address(调试通道IP地址)"
      • 您可以通过在UFE中点击 "Show All Target Information(显示所有目标信息)"来找到这个地址。
    • 确保端口号设置为 13002
  • 活动的统计数据将会通过UDP连接开始动态载入。
  • 您可以使用 File(文件) -> Save(保存)命令来把不活的数据保存到磁盘上。

查看统计数据:

  • 在StatsViewer(统计数据查看器)工具中找到一个 .ustats 文件,或者 Connect(连接到) 活动的游戏会话。
  • 交互式的图表将在开头为您显示帧频率,以便您可以看到停顿及趋势。
  • 从左侧的栏中 拖拽并放下 统计数据到图表上,以便显示统计数据。
  • 点击 图表来选择一个帧,并查看那个帧的统计数据。
  • 双击 图表来为那帧 open the Call Graph(打开调用图表)
  • 右击左侧栏中的统计数据来"View Frames by Criteria(根据条件查看帧)" (比如仅查看FPS<20的帧,等。
  • 使用菜单项来切换视图模式(相对于事件的帧编号,范围内的/全部 数据)。

其它注意:

  • 不要在LTCG模式下进行工作(除非您在本地定义了 #define STATS ), 请使用发布版本。
  • 活动的统计数据捕获仍然是有些问题的(丢失帧、滚动也有点奇怪等)。

关于进行实时统计数据捕获的更多信息,请参照这个页面

   • 游戏性分析器:这里概述了如何读取和分析游戏性代码中所花费的时间数据。

请使用Script Profiling(脚本分析)来调整UnrealScript的性能

Gameplay Profiler(游戏性分析器) 提供了关于您的脚本代码中的一些昂贵函数的很多重要信息。捕获一个较短采样时间间隔内的分析数据并给于您到热点区的及时访问是十分地快的。

要想捕获脚本分析器数据:

  • 在控制台中输入 PROFILEGAME START 来开始捕获数据。
  • 当您完成后,输入 PROFILEGAME STOP 来停止捕获数据并把数据保存到磁盘中。
  • 分析数据将会被保存到 \UnrealEngine3\\Profiling\文件夹中。
    • 在控制台游戏平台上,将会通过UnrealConsole把统计数据自动地转换到PC上。
  • 运行GameplayProfiler (游戏性分析器)并加载文件(比如 -07.15-18.58.uprof)。

请参照 游戏性分析器文档获得更多的信息。

注意: 在很多情况下,状态查看器提供的脚本分析数据要比GameplayProfiler(游戏性分析器)提供的数据更加详细,这要以更多的运行时间消耗为代价。当捕获统计数据时,仅要确保 #define STAT SLOW1 ,那么StatsViewer(统计数据查看器)便可以显示每一帧的所有UnrealScript调用图。

游戏机平台的性能

针对游戏机平台的性能信息在子页面上进行了介绍。

要想获得所有的Stat Commands(统计命令)列表,请参照统计数据命令描述页面。

要想获得所有的Console Commands (控制台命令)列表,请参照控制台命令页面。