GPU分析

如何优化游戏的GPU需求。

Choose your operating system:

Windows

macOS

Linux

GPU有许多并行运行的单元,在帧的不同序列上被不同的单元绑定很常见。由于存在这种性质的行为,在搜寻瓶颈时确定GPU开销的去向以及了解GPU瓶颈是什么很有帮助。

Unreal Insights 是一款帮助开发人员识别瓶颈的应用程序,在优化性能时很有用。大致来说,Unreal Insights是一个独立的分析系统,它与虚幻引擎集成,可以收集、分析和可视化引擎发出的数据。

如何设置Unreal Insights

Unreal Insights工具随虚幻引擎一起提供。你可以在 Engine/Binaries/Win64 的引擎源目录文件夹,或启动程序引擎目录 Program Files/EpicGames/EngineVersion/Engine/Binaries/Win64/UnrealInsights.exe 中找到 UnrealInsights.exe

UnrealInsights.png

如果你下载UE源代码,并在本地编译,通过在开发(Development)或发布(Shipping)模式下构建整个解决方案,或通过直接构建 UnrealInsights 项目,你可以编译它。

UnrealInsightsBuild.png

你找到或构建编译的程序( UnrealInsights.exe )后,在你要用于记录数据或查看实时会话的设备上运行它。

记录GPU追踪数据

追踪 是一种结构化的日志记录框架,用于追踪正在运行流程中的仪表测量事件。Insights包含默认预设(-trace=default),可以自动追踪有关CPU、帧、日志和书签的信息,这些信息可以帮助你识别需要优化的其他区域。

要追踪项目的GPU追踪数据,请使用命令行参数启动你的项目(在独立或打包构建中)。

-trace= default, gpu

或者,按波浪号(~)键并输入命令,找到控制台的命令窗口

Trace.Start[gpu]

查看GPU追踪数据

追踪数据存储在 UnrealInsights/Saved/TraceSeissons 文件夹的追踪存储目录(Trace Store Directory)中,你可以在其中查看。

TraceStoreDirectory.png

你也可以在Unreal Insights应用程序中双击实时会话,打开 Insights Viewer

TraceSessionsInsights.png

分析GPU追踪数据

Insights Viewer 包含用于浏览和可视化性能数据的 Timing Insights 窗口。在Timing Insights窗口中,你将看到CPU和GPU的逐帧性能数据。你可以查看渲染(Rendering)和RHI线程(RHI Thread)轨道上的CPU计时事件,它们是可以与GPU计时事件关联的最重要事件。

GpuTrack.png

计时(Timing)面板 将显示单个追踪事件,并提供亚微秒级精度的时间测量。这些事件垂直堆叠,从而指示范围并并使用单独的轨道显示不同线程上的活动。在轨道显示中,事件按线程分解,垂直划分以便显示范围,并根据它们的开始和结束时间水平定位。

TimingPanel.jpg

将鼠标悬停在计时(Timing)面板(1)中的计时器事件上时出现的提示文本。同一线程上的嵌套事件堆栈(2)。

日志(Log)面板 将显示UE4会话中的所有日志(由UE_LOG调用生成)。日志可以按冗长度和类别筛选,就像编辑器的输出日志窗口(Output Log)一样。

LogPanel.jpg

日志提供在计时(Timing)视图中显示为垂直标识线的功能。默认情况下,仅书签显示为标识线。但是,这可以使用快捷键 M ,或通过右键点击 书签(Bookmarks) 轨道并从上下文菜单中选择 日志(Logs) 来更改。

BookMarks.png

找到Insights浏览器(Insights Browser),显示日志类别。(1). 书签轨道。(2). 上下文菜单将筛选你的书签轨道显示。

Unreal Insights提供强大的 动画 网络 UI 分析功能。

虚幻前端

下面的信息详细说明了用于使用 虚幻前端 分析GPU开销的命令。此工具的分析功能已被 Unreal Insights 取代。

虚幻前端 是一款旨在简化和加快日常视频游戏开发和测试任务的工具,例如准备游戏版本、将它们部署到设备以及启动它们。

ProfileGPU命令

ProfileGPU命令可以识别各种通道的GPU开销,有时甚至是绘制调用的开销。 你可以使用基于鼠标的UI或文本版本。你可以使用 r.ProfileGPU.ShowUI 抑制UI。数据基于GPU时间戳, 通常非常准确。某些优化可能会降低数据的可靠性,所以对所有数据都保持质疑是一件好事。我们发现,一些驱动程序 倾向于在使用着色器几秒钟后优化着色器成本。这点可能很明显,等待片刻或换个时间再次测量很有帮助,从而更有把握。

| ProfileGPU.png |

| 控制台:ProfileGPU |

| 快捷键:Ctrl+Shift+, |

...

 1.2% 0.13ms   ClearTranslucentVolumeLighting 1 draws 128 prims 256 verts

42.4% 4.68ms   Lights 0 draws 0 prims 0 verts

   42.4% 4.68ms   DirectLighting 0 draws 0 prims 0 verts

       0.8% 0.09ms   NonShadowedLights 0 draws 0 prims 0 verts

          0.7% 0.08ms   StandardDeferredLighting 3 draws 0 prims 0 verts

          0.1% 0.01ms   InjectNonShadowedTranslucentLighting 6 draws 120 prims 240 verts

      12.3% 1.36ms   RenderTestMap.DirectionalLightImmovable_1 1 draws 0 prims 0 verts

          1.4% 0.15ms   TranslucencyShadowMapGeneration 0 draws 0 prims 0 verts

...

ProfileGPU将显示光源名称,这样美术师可以更轻松地优化正确的光源。

查看每帧的大概成本,并确定合理项(例如,绘制调用量大、材质复杂、三角形网格体密集、视图距离远):

EarlyZPass

默认情况下,我们使用部分z通道。DBuffer贴花需要完整的Z通道。你可以使用 r.EarlyZPass r.EarlyZPassMovable 进行自定义。

基础通道(Base Pass)

使用延迟着色时,简单的材质可能会受到带宽限制。实际的顶点和像素着色器在材质图表中定义。动态对象上的间接光照会产生额外成本。

阴影贴图渲染(Shadow map rendering)

实际的顶点和像素着色器在材质图表中定义。像素着色器仅用于遮罩材质或半透明材质。

阴影投影/过滤(Shadow projection/filtering)

调整着色器开销,在大多数光源上投射 r.ShadowQuality.Disable 阴影。考虑静态光源或固定光源。

遮蔽剔除(Occlusion culling)

HZB遮蔽具有较高的恒定开销,但每个对象的开销较小。切换 r.HZBOcclusion 可以查看不打开它是否会更佳。

延迟光照(Deferred lighting)

这与接触的像素成比例,并且在光照函数、IES配置文件、阴影接收、区域光照和复杂着色模型方面的开销更高。

平铺延迟光照(Tiled deferred lighting)

切换 r.TiledDeferredShading 可以禁用GPU光源,或使用 r.TiledDeferredShading.MinimumCount 定义何时使用平铺方法或非延迟方法。

环境反射(Environment reflections)

切换 r.NoTiledReflections 可以使用非平铺方法,除非你的探针很少,否则这种方法通常较慢。

环境光遮蔽(Ambient occlusion)

可以调整质量,你可以使用多个通道来实现高效的大规模效果。

后期处理(Post-processing)

一些通道是共享的,因此切换显示标记可以查看效果是否匹配性能。

某些通道可能会对之后的通道产生影响。示例如下:

  • 全部EarlyZ通道会导致更多的绘制调用和一些GPU开销,但它避免了基础通道中的像素处理,可以大幅降低这部分开销。

  • 优化HZB可能会导致剔除更加保守。

  • 如果屏幕上大部分区域处于阴影中,启用阴影可以降低灯光源的光照开销。

什么是GPU瓶颈?

通常,性能开销会随着像素的数量变化而变化。若要测试,你可以使用 r.SetRes 改变渲染分辨率,或在编辑器中缩放视口。

使用 r.ScreenPercentage 更加方便,但请记住,一旦使用该功能,就会增加一些额外的上取样开销。

如果你看到明显的性能变化,则意味着你受到了像素相关因素的限制。通常是内存带宽(读写)或数学限制(ALU),但在极少数情况下,某些特定单元已饱和(例如,MRT导出)。如果你可以降低相关通道的内存(或数学计算)并看到性能差异,你就会知道它是受内存带宽(或ALU单元)的限制。

变化不一定相同,这只是测试。现在你知道了,必须降低开销才能提高性能。

阴影贴图分辨率不随屏幕分辨率的变化而变化(使用 r.Shadow.MaxResolution ),但是除非你的阴影投射遮罩材质或半透明材质区域非常大,否则不受像素着色器限制。通常,阴影贴图渲染受顶点处理或三角形处理的约限制(原因:网格体密集、没有LOD、曲面细分、WorldPositionOffset使用)。

阴影贴图渲染开销会因光源数量、立方体贴图边数和光视锥体中投射阴影对象数量的变化而变化。这是非常常见的瓶颈,仅较大的内容更改才能降低开销。

高度曲面细分的网格体(其中线框显示为纯色)可能会导致四边形利用率低下。这是因为GPU在2x2像素块中处理三角形,并稍后拒绝三角形外的像素。这是mipmap计算所必需的。对于较大的三角形,这不是问题,

但是如果三角形很小或很细长,性能会受到影响,因为处理的像素很多,但实际上对图像有贡献的像素很少。延迟着色可以改善这种情况,因为我们对光照获得了非常好的四边形利用率。基础通道期间问题仍将存在,因此复杂材质的渲染可能会相当慢。

解决方案是使用密度较小的网格体。有了细节级别网格体,这只能在有问题的地方(远距离)完成。

你可以调整_r.EarlyZPass_,查看你的场景是否会从完整的早期Z通道中受益(更多的绘制调用,在基础通道期间减少过度绘制)。

如果更改分辨率无关紧要,你可能会受到顶点处理(顶点着色器或曲面细分)开销的限制。

通常,你必须更改内容才能验证这一点。通常原因包括:

  • 顶点太多(使用细节级别网格体)。

  • 复杂的世界位置偏移/置换材质,使用具有较差MIP映射的纹理(调整材质)。

  • 曲面细分(尽可能避免,调整曲面细分因子,最快的方法:显示曲面细分,一些硬件在较大的曲面细分级别下会严重缩放)。

  • 许多UV或法线接缝会导致顶点更多(查看展开的UV - 许多岛状区很糟糕,平面着色网格体每个三角形有3个顶点)。

  • 顶点属性过多(额外的UV通道)。

  • 验证顶点数是否合理,某些导入程序代码可能未焊接顶点(组合具有相同位置、UV和法线的顶点)。

较少情况下,你会受到其他因素的限制。可能包括:

  • 对象开销(很有可能是CPU开销,但可能也有一些GPU开销)。

  • 三角形设置开销(具有低价顶点着色器的高精度多边形网格体(例如阴影贴图静态网格体)很少出现此问题)。

  • 使用细节级别(LOD)网格体。

  • 视图开销(例如,HZB遮蔽剔除)。

  • 场景开销(例如GPU粒子模拟)。

实时GPU分析器

实时GPU分析器将为主要渲染类别提供实时的逐帧统计数据。要使用实时GPU分析器,请按 反引号(Backtick) 键打开控制台,然后输入 统计数据GPU(stat GPU) ,并按 Enter 。你还可以通过 视口选项(Viewport Options) 下拉菜单中的 统计数据(Stat) 子菜单,启动实时GPU分析器。

GPU_Stats.png

统计数据是累加且不分层级的,因此你无需深入挖掘事件树即可查看主要类别。例如, 阴影投影(Shadow Projection) 是所有视图中所有光源的所有阴影投影的总和。当你的作品运行时,屏幕上的GPU统计数据提供了GPU负载的简单可视化细分。统计数据也可用于即时衡量变化的影响;例如,在更改控制台变量、在编辑器中修改材质或动态修改和重编译着色器(重编译着色器已更改)时的影响。当作品运行以供稍后分析时,GPU统计数据可以记录到文件中。

与现有统计数据一样,你可以使用控制台命令 stat startfile stat stopfile 将统计数据记录到 ue4stats 文件中,然后通过在 虚幻前端工具 中打开文件来查看统计数据。

Saved_Profile.png

使用虚幻前端分析GPU。界面上将显示总时间、后处理时间和基本通道时间。

统计数据在代码中声明为浮点计数器,例如:

DECLARE_FLOAT_COUNTER_STAT(TEXT("Postprocessing"), Stat_GPU_Postprocessing, STATGROUP_GPU);

然后可以使用引用这些统计数据名称的SCOPED_GPU_STAT宏检测渲染线程上的代码块。这些工作类似于SCOPED_DRAW_EVENT。例如:

SCOPED_GPU_STAT(RHICmdList, Stat_GPU_Postprocessing);

未明确检测的GPU工作将包含在全面的[未说明]统计数据中。如果它变得太高,则表明需要一些额外的 SCOPED_GPU_STAT 事件来处理丢失的工作。

值得注意的是,与绘制事件不同,GPU统计数据是累加的。你可以为同一统计数据添加多个条目,这些条目会在整个框架中聚合。在某些受CPU限制的情况下,GPU计时可能会受到CPU瓶颈(气泡)的影响,此时GPU正在等待CPU追上。因此如果在绘制线程时间很长的情况下看到意外结果,请考虑这种可能性。在PlayStation 4上,我们通过从计时中排除命令列表提交之间的时间来更正这些气泡。在未来的版本中,我们会将该功能扩展到其他现代渲染API。

欢迎帮助改进虚幻引擎文档!请告诉我们该如何更好地为您服务。
填写问卷调查
取消