您的位置:首页 > 产品设计 > UI/UE

UE3 基本的分析及优化技术

2015-10-23 18:59 344 查看
概述
STAT命令
准备分析环境
STAT UNIT
编译配置
关闭垃圾回收确认功能
以 Final Release(最终发布版本)模式编译脚本

禁用VSync
使用STAT SLOW

帮助和技巧
关闭某些功能
面向墙壁
产生属于一种类型的N个对象

引导时间分析
Profile Nodes(分析节点)
Profile Node(分析节点)查看器


概述

以下部分将为您讲解用于跟踪性能问题、瓶颈及停顿现象的最有用的工具。

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

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

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

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

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


STAT命令

当调试、测试或分析游戏时,能够快速并容易地直接在游戏中查看及分析有意义的数据是非常必要的。通过使用STAT控制台命令,虚幻引擎3提供了用于查看关于游戏和引擎各个方面的大量统计数据的功能,并将它们作为平头显示信息(HUD)显示到屏幕上。

Stat 命令描述页面包含了所有可用的统计命令的完整列表以及关于每个命令所显示的各种测量值的介绍。


准备分析环境

首先,请确保在运行游戏时总是打开STAT UNIT命令。
配置您的编译环境。当测量性能时请使用ShippingDebugConsole
(LTCG)版本;当调试性能时请使用Release(发布)版本。
请确保关闭任何垃圾日志输出或关闭那些将影响性能结果的调试代码。
关闭垃圾回收确认,因为它将会导致帧停顿。
最终发布模式编译脚本。
禁用VSync,以便可以识别出瓶颈问题,即时在较快的帧上也可以发现瓶颈问题。



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_ASSUMPTIONS 为 0 。
传入 -NoVerifyGC 命令行参数。



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

当启用日志功能和断言功能时,UnrealScript的性能会有很大的差别。获得接近于发行版本的游戏性能的最简单方法是以 Final Release(最终发布) 模式编译脚本,该模式可以自动地从编译后的字节码中剥离性能消耗较高的函数调用。您可以通过以下几种方法之一来编译 Final Release(最终发布) 版本的脚本:
虚幻前端, 选择 Cooking(烘焙) 标签并启用 "Cook Final
Release Scripts(烘焙最终发布版本的脚本)"
 复选框。现在,当您运行烘焙器或通过UFE启动游戏时,将会编译并使用 Final Release(最终发布) 版本的脚本。
向 make 命令行开关中传入 -Final_Release 命令行参数。



禁用VSync

要想获得最好的效果,您需要关闭 VSync (在呈现帧之前等待垂直的折回)。否则,帧时间将会被填充到游戏的刷新频率上,这会导致更难获得精确的图像。要想关闭VSync :
传入 -NoVSync 命令行选项到游戏中。
或者,在Unreal Frontend(虚幻前端)的 Game 变迁中启用 "No
VSync"
 复选框。



使用STAT SLOW

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

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

示例: 
STAT SLOW 0.01 10


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


帮助和技巧

以下部分介绍了在优化性能问题时需要记住的一些帮助和技巧。


关闭某些功能

一般,游戏有很多令人兴奋但是性能消耗较高的性能。除了当您做很多这些性能消耗昂贵的事情时或者当您有一个复杂场景并且这些性能消耗较大的操作导致场景运行较慢时外,那些功能一般都很好。您可以花费数小时的时间来进行优化,最终获得20-40%的性能改进,但这些改进可能不足以使得场景变得足够的快。另一种方法是关闭那个功能!! 这对于那些当有很多屠杀发生时很难注意到的事情或者那些位于很远距离发生的事情来说是个很好的策略。

另外,"关闭某些功能"是进行分析时的一个很好的技术。有时候您需要知道花费时间对某些东西进行优化是否值得。那么完全地关掉那个功能便是验证它的最好方法: "如果我们免除这个功能,那么我们在帧时间预算方面获得什么结果"。

应用示例:
距离玩家很远的敌人不必总是需要在地面上产生小的血迹贴花(比如,射击流血的特效)。
关卡设计人员知道的玩家永远不会触及的敌人不需要产生血迹或丢下武器。
对于一个复杂的SkeletalControl(骨架控制)来说,当拥有者不可见时不去更新它。
当布料不在场景中时便可以不仿真布料! :-)


面向墙壁

许多时候,代码正在更新那些当它们不可见时实际上不需要渲染的东西。进入到关卡中,面向墙壁,做所有您可以做的正常的分析,这是查看对象是否在不需要更新时更新了它们本身的最好方法。

当然,有些东西在不可见时也需要更新,但是对于大部分多对象来说,不进行持续的更新也是可以的。


产生属于一种类型的N个对象

通常,在游戏中您将会看到有大量同种类型的敌人攻击您,并且此时游戏是比较慢的。由于使用了那种敌人类型导致某些东西变慢了! 问题是引擎的其它方面阻挡您轻松地查看什么东西使运行较慢。但是有一个较好的解决方法是获得一个测试关卡,在那个测试关卡中产生N个这种类型的敌人,然后分析它。这样便可以很容易地看到影响性能的热点区域在哪里!

这是一个很容易应用的技术。简单地执行以下步骤即可:
在测试关卡中放置N个有问题的对象!
分析!


引导时间分析

在引导及加载时间处理过程中,一般知道每一秒时间都用在何处是非常有用的。如果您想获得这样的信息,可以像代码中添加简单的分析节点来帮助您分析这段时间。另外,任何写入到log/tty 文件中的调试信息都有时间戳,这些也可以用作为简单的分析机制。


Profile Nodes(分析节点)

注意: 目前UDK中没有提供该功能,正在审查将其加入到以后的版本中。

UnMisc.h中有一些简单的函数,用于辅助您分析应用程序时间,如下所示:
/**
* Creates the entry point for a simple profiling node
*
* @param TimerName - The name of the section
*/
void ProfNodeStart(const TCHAR * TimerName);

/**
* Stops the current scope and logs out the timing information
*/
void ProfNodeStop();

/**
* @param Threshold - The threshold in seconds below which timing information will not be printed out. Default is 0.1f
* @return The old time treshold
*/
FLOAT ProfNodeSetTimeThresholdSeconds(FLOAT Threshold);

/**
* @param Depth The depth level above which timings will always be printed out.  Default is 2.
* @return The old depth threshold
*/
INT ProfNodeSetDepthThreshold(INT Depth);


这些函数可以从UnrealScript中直接获得,或者可以在代码中使用宏获得:
PROFNODE_SCOPED(Name)  //auto start-stop within included scope
PROFNODE_START(Name)    // manual start
PROFNODE_STOP()     // manual stop last started node


一旦将这些函数放到代码中,您必须在运行启动了日志记录和PROFNODE_ENABLED定义集合的版本的应用程序。输出数据可以直接从应用程序日志中查看,但是为了方便查看和评估,您可以将整个输出日志另存为文本文件,并使用ProfNodeVisualizer工具进行查看。


Profile Node(分析节点)查看器

分析节点查看器:



可以在/Binaries文件夹中找到Profile Node Visualizer (分析节点查看器)(是否包含在UDK中正在经过审查)。

启动该工具并选择File(文件)->Load File(加载文件),并从设备浏览到您导出的.log文件(或者复制您的设备输出信息到一个文档文件,并将其保存为扩展名为.log的文件)。该工具将会以层次结构视图显示所捕获的每个线程的所有事件。将会对节点进行标色,根据他们占用整个树形结构事件时间的百分比来确定红色的程度。

您也可以输入搜索字符串到'Search(搜索)'框来查找任何文本第一次出现的位置。

右击并选择'Export From Here(从这里导出)...',将导出一个以当前选中节点(作为根节点)所包含的所有节点在内的文本文件。

概述
STAT命令
准备分析环境
STAT UNIT
编译配置
关闭垃圾回收确认功能
以 Final Release(最终发布版本)模式编译脚本

禁用VSync
使用STAT SLOW

帮助和技巧
关闭某些功能
面向墙壁
产生属于一种类型的N个对象

引导时间分析
Profile Nodes(分析节点)
Profile Node(分析节点)查看器


概述

以下部分将为您讲解用于跟踪性能问题、瓶颈及停顿现象的最有用的工具。

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

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

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

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

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


STAT命令

当调试、测试或分析游戏时,能够快速并容易地直接在游戏中查看及分析有意义的数据是非常必要的。通过使用STAT控制台命令,虚幻引擎3提供了用于查看关于游戏和引擎各个方面的大量统计数据的功能,并将它们作为平头显示信息(HUD)显示到屏幕上。

Stat 命令描述页面包含了所有可用的统计命令的完整列表以及关于每个命令所显示的各种测量值的介绍。


准备分析环境

首先,请确保在运行游戏时总是打开STAT UNIT命令。
配置您的编译环境。当测量性能时请使用ShippingDebugConsole
(LTCG)版本;当调试性能时请使用Release(发布)版本。
请确保关闭任何垃圾日志输出或关闭那些将影响性能结果的调试代码。
关闭垃圾回收确认,因为它将会导致帧停顿。
最终发布模式编译脚本。
禁用VSync,以便可以识别出瓶颈问题,即时在较快的帧上也可以发现瓶颈问题。



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_ASSUMPTIONS 为 0 。
传入 -NoVerifyGC 命令行参数。



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

当启用日志功能和断言功能时,UnrealScript的性能会有很大的差别。获得接近于发行版本的游戏性能的最简单方法是以 Final Release(最终发布) 模式编译脚本,该模式可以自动地从编译后的字节码中剥离性能消耗较高的函数调用。您可以通过以下几种方法之一来编译 Final Release(最终发布) 版本的脚本:
虚幻前端, 选择 Cooking(烘焙) 标签并启用 "Cook Final
Release Scripts(烘焙最终发布版本的脚本)"
 复选框。现在,当您运行烘焙器或通过UFE启动游戏时,将会编译并使用 Final Release(最终发布) 版本的脚本。
向 make 命令行开关中传入 -Final_Release 命令行参数。



禁用VSync

要想获得最好的效果,您需要关闭 VSync (在呈现帧之前等待垂直的折回)。否则,帧时间将会被填充到游戏的刷新频率上,这会导致更难获得精确的图像。要想关闭VSync :
传入 -NoVSync 命令行选项到游戏中。
或者,在Unreal Frontend(虚幻前端)的 Game 变迁中启用 "No
VSync"
 复选框。



使用STAT SLOW

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

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

示例: 
STAT SLOW 0.01 10


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


帮助和技巧

以下部分介绍了在优化性能问题时需要记住的一些帮助和技巧。


关闭某些功能

一般,游戏有很多令人兴奋但是性能消耗较高的性能。除了当您做很多这些性能消耗昂贵的事情时或者当您有一个复杂场景并且这些性能消耗较大的操作导致场景运行较慢时外,那些功能一般都很好。您可以花费数小时的时间来进行优化,最终获得20-40%的性能改进,但这些改进可能不足以使得场景变得足够的快。另一种方法是关闭那个功能!! 这对于那些当有很多屠杀发生时很难注意到的事情或者那些位于很远距离发生的事情来说是个很好的策略。

另外,"关闭某些功能"是进行分析时的一个很好的技术。有时候您需要知道花费时间对某些东西进行优化是否值得。那么完全地关掉那个功能便是验证它的最好方法: "如果我们免除这个功能,那么我们在帧时间预算方面获得什么结果"。

应用示例:
距离玩家很远的敌人不必总是需要在地面上产生小的血迹贴花(比如,射击流血的特效)。
关卡设计人员知道的玩家永远不会触及的敌人不需要产生血迹或丢下武器。
对于一个复杂的SkeletalControl(骨架控制)来说,当拥有者不可见时不去更新它。
当布料不在场景中时便可以不仿真布料! :-)


面向墙壁

许多时候,代码正在更新那些当它们不可见时实际上不需要渲染的东西。进入到关卡中,面向墙壁,做所有您可以做的正常的分析,这是查看对象是否在不需要更新时更新了它们本身的最好方法。

当然,有些东西在不可见时也需要更新,但是对于大部分多对象来说,不进行持续的更新也是可以的。


产生属于一种类型的N个对象

通常,在游戏中您将会看到有大量同种类型的敌人攻击您,并且此时游戏是比较慢的。由于使用了那种敌人类型导致某些东西变慢了! 问题是引擎的其它方面阻挡您轻松地查看什么东西使运行较慢。但是有一个较好的解决方法是获得一个测试关卡,在那个测试关卡中产生N个这种类型的敌人,然后分析它。这样便可以很容易地看到影响性能的热点区域在哪里!

这是一个很容易应用的技术。简单地执行以下步骤即可:
在测试关卡中放置N个有问题的对象!
分析!


引导时间分析

在引导及加载时间处理过程中,一般知道每一秒时间都用在何处是非常有用的。如果您想获得这样的信息,可以像代码中添加简单的分析节点来帮助您分析这段时间。另外,任何写入到log/tty 文件中的调试信息都有时间戳,这些也可以用作为简单的分析机制。


Profile Nodes(分析节点)

注意: 目前UDK中没有提供该功能,正在审查将其加入到以后的版本中。

UnMisc.h中有一些简单的函数,用于辅助您分析应用程序时间,如下所示:
/**
* Creates the entry point for a simple profiling node
*
* @param TimerName - The name of the section
*/
void ProfNodeStart(const TCHAR * TimerName);

/**
* Stops the current scope and logs out the timing information
*/
void ProfNodeStop();

/**
* @param Threshold - The threshold in seconds below which timing information will not be printed out. Default is 0.1f
* @return The old time treshold
*/
FLOAT ProfNodeSetTimeThresholdSeconds(FLOAT Threshold);

/**
* @param Depth The depth level above which timings will always be printed out.  Default is 2.
* @return The old depth threshold
*/
INT ProfNodeSetDepthThreshold(INT Depth);


这些函数可以从UnrealScript中直接获得,或者可以在代码中使用宏获得:
PROFNODE_SCOPED(Name)  //auto start-stop within included scope
PROFNODE_START(Name)    // manual start
PROFNODE_STOP()     // manual stop last started node


一旦将这些函数放到代码中,您必须在运行启动了日志记录和PROFNODE_ENABLED定义集合的版本的应用程序。输出数据可以直接从应用程序日志中查看,但是为了方便查看和评估,您可以将整个输出日志另存为文本文件,并使用ProfNodeVisualizer工具进行查看。


Profile Node(分析节点)查看器

分析节点查看器:



可以在/Binaries文件夹中找到Profile Node Visualizer (分析节点查看器)(是否包含在UDK中正在经过审查)。

启动该工具并选择File(文件)->Load File(加载文件),并从设备浏览到您导出的.log文件(或者复制您的设备输出信息到一个文档文件,并将其保存为扩展名为.log的文件)。该工具将会以层次结构视图显示所捕获的每个线程的所有事件。将会对节点进行标色,根据他们占用整个树形结构事件时间的百分比来确定红色的程度。

您也可以输入搜索字符串到'Search(搜索)'框来查找任何文本第一次出现的位置。

右击并选择'Export From Here(从这里导出)...',将导出一个以当前选中节点(作为根节点)所包含的所有节点在内的文本文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: