UE4 中的 PGO

910 字
5 分钟
UE4 中的 PGO

简介#

PGO(Profile Guided Optimization)是一种基于 LLVM 的编译时优化,通过使用运行时收集的分析数据来指导编译器进行优化。截至 UE5.0 版本,Epic 对 PC、Android 以及各 Console 平台都进行了配置。网路上很少有 PGO 相关的文章,这篇文章旨在尝试 PGO 的使用流程。

流程#

按照 Epic 的流程,PGO 可以直接启用,也可以搭配Gauntlet 自动测试框架集成到自动测试流程中使用。关于 Gauntlet 框架的可参考官方文档 Gauntlet 自动化框架。PGO 整体的大致流程如图:

Progress2
Progress2

构建用于 PGO 的版本#

首先需要构建用于收集分析数据的 PGO 版本。添加命令行-PGOProfile以开启相应的宏:

/* --- TargetRules.cs --- */
/// <summary>
/// Whether to enable Profile Guided Optimization (PGO) instrumentation in this build.
/// </summary>
[CommandLine("-PGOProfile", Value = "true")]
[XmlConfigFile(Category = "BuildConfiguration")]
public bool bPGOProfile = true;
/* --- UEBuildTarget.cs --- */
if (Rules.bPGOProfile)
{
GlobalCompileEnvironment.Definitions.Add("ENABLE_PGO_PROFILE=1");
}
else
{
GlobalCompileEnvironment.Definitions.Add("ENABLE_PGO_PROFILE=0");
}

PGO 版本中,宏ENABLE_PGO_PROFILE应该被启用,否则不会输出 PGO 的临时文件:

/* --- PlatformMisc.cpp --- */
#if ENABLE_PGO_PROFILE
// Write the PGO profiling file on a clean shutdown.
extern void PGO_WriteFile();
PGO_WriteFile();
#endif

可以通过在 build 时传入指定的参数-PGOProfile来控制是否开启ENABLE_PGO_PROFILE。默认情况下打开 PGOProfile 后也会打开 LTO,因此链接时间会变得非常长。

运行时收集数据#

接下来需要启动游戏正常游玩、正常退出。因为只有在RequestExit()时才会在PGO_WriteFile中调用__llvm_profile_write_file即写入扩展名为*.profraw的临时文件。 该临时文件的输出目录可由命令行参数指定,但由于实现的问题,在不同的平台中,命令行参数有所不同,在启动时不指定输出目录,便会将该文件写入到默认位置,详情可参照PGO_GetOutputDirectory函数。

创建 Gauntlet 的测试用例<可选>#

如果需要集成到自动测试流程中,需要创建测试用例并添加该测试至 Gauntlet 的项目里。这个过程可以参考Engine\Source\Programs\AutomationTool\Gauntlet\Unreal\Game下的 Samples。 Gauntlet 中已经有一个 PGO 的测试节点Gauntlet.UnrealPGONode.cs,其中 PGOConfig 有下面几个参数,可通过命令行传入给 UAT,其中ProfileOutputDirectory是必需的。

/// <summary>
/// Output directory to write the resulting profile data to.
/// </summary>
[AutoParam("")]
public string ProfileOutputDirectory;
/// <summary>
/// Directory to save periodic screenshots to whilst the PGO run is in progress.
/// </summary>
[AutoParam("")]
public string ScreenshotDirectory;
[AutoParam("")]
public string PGOAccountSandbox;
[AutoParam("")]
public string PgcFilenamePrefix;

使用 UAT 运行指定的测试用例。可以加入到 bat 文件里,方便集成到 Jenkins 一类的 CI 里:

Terminal window
rem path for RunUAT.bat
set UAT_PATH=RunUAT.bat
rem project name
set PRJ_NAME={ProjectName}
rem staging path
set STAGING_DIR={EngineRoot}\{ProjectName}\Saved\StagedBuilds
rem test command
set TEST_CMD=RunUnreal
rem test name
set TEST_NAME=PGOTest
rem profdata output path
set PROFILE_OUTPUT_PATH={ProjectName}\Saved\Automation\PGO\
rem screenshot path
set SCREENSHOT_DIRECTORY={ProjectName}\Saved\Automation\PGO\Screenshot\
rem platform Name
set PLATFORM=Android
rem build configuration
set CONFIG=Test
rem ********************* Start Gauntlet Test *********************
%UAT_PATH% %TEST_CMD% -project=%PRJ_NAME% -platform=%PLATFORM% -configuration=%CONFIG% -build=%STAGING_DIR%\%PLATFORM% -test=%TEST_NAME% -ProfileOutputDirectory=%PROFILE_OUTPUT_PATH% -ScreenshotDirectory=%SCREENSHOT_DIRECTORY%
rem ********************* End Gauntlet Test *********************
pause

注意事项#

  • PGO 本质上是编译器优化,因此随着优化等级的提高,有可能会暴露出代码中一些原本不存在的问题。
  • 随着版本的迭代,代码不断更新,原本 PGO 收集的数据在用于新版本的优化时的效果会大打折扣。
  • Profile 数据会有额外的内存占用。

参考资料#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

UE4 中的 PGO
https://yohiro.games/posts/profile-guided-optimization-in-unreal/
作者
Yohiro
发布于
2020-08-17
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Yohiro
去码头整点薯条。
分类
标签
站点统计
文章
27
分类
5
标签
55
总字数
110,877
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录