使用英特尔® 图形性能分析器分析实际游戏性能

作者:郭胜、Philipp Gerasimov、Neal P. 和 Bonnie Aona
英特尔公司软件与服务事业部

注:本文围绕英特尔 GPA 3.0 版编写,包含许多不受英特尔 GPA 任何具体版本限制的性能提示和指南。不久之后,本文将针对 4.0 版进行更新。

下载文章

下载使用英特尔® 图形性能分析器分析实际游戏性能 [PDF 2MB]

摘要

使用英特尔® 图形性能分析器(英特尔® GPA)以及本文介绍的性能分析方法,改善游戏在英特尔® 核芯显卡(IHD)平台上的性能。英特尔 GPA 是一个图形性能优化工具套件,可以让开发人员查看、隔离和解决基于 Microsoft* DirectX 的游戏和其它图形应用的图形性能问题。除了本文提供的信息,我们建议你阅读英特尔核芯显卡快速参考指南以及英特尔集成显卡概述页面上其它关于英特尔显卡的信息,了解如何高效使用英特尔核芯显卡和英特尔集成显卡的各项特性改善游戏性能。

1. 简介

视频游戏在集成显卡上的性能日益成为游戏开发人员关注的一个重要问题。这主要基于两方面的原因:一方面,最新的英特尔集成显卡平台提供了一套高性能特性;例如,英特尔® 4 系列高速芯片组支持 Shader Model 4.0 [SM4.0] 和 DirectX* 9/10 规格,能够满足当今大多数游戏的需求。另一方面,集成显卡的高性价比促使英特尔® 4 系列高速芯片组在笔记本电脑市场迅速普及,增加了它作为游戏玩家的图形解决方案的可行性。笔记本电脑带来的不仅仅是移动平台向传统游戏设置的扩展,更是一个进军休闲和社交游戏市场的机会。优化游戏在集成显卡上的性能,是推动游戏取得商业性成功的关键,因为它将扩大你的潜在市场。本文提供了一些非常实用的游戏优化建议和示例。

开始分析和优化游戏之前,你需要在心中确定一个明确的目标,这一点非常重要。例如,你可能希望在采用特定游戏和图形设置的 1280x1024 屏幕上实现 30 帧/秒的速率。英特尔 GPA 能够帮助你确定游戏在某些方面存在的性能瓶颈,例如过度的顶点着色器使用或硬件/驱动带宽限制。另外,英特尔 GPA 也是一个可视化工具,显示具体代码或资产变更对游戏产生的正面或负面影响。

游戏开发人员可能也想针对特定的目标平台分析和优化游戏性能。基于最新英特尔核芯显卡芯片组的笔记本电脑是最常见的主流游戏平台。由于大量的系统都采用此类显卡芯片组,你将拥有一个非常大的安装群。另一方面,铁杆游戏玩家更可能会不计成本地购买最高性能系统。因此,你需要确保游戏在这些平台上实现每一种可能的视觉效果,增加游戏销量。

由于英特尔 GPA 可以在大多数基于 Microsoft DX 9、DX10.0 或 DX 10.1 的应用上运行,我们能够帮助你了解英特尔核芯显卡平台支持的最佳 DX 层优化。例如,针对笔记本电脑优化游戏的基本场景渲染之后,这些变更将会应用到其它平台。然后,你可以确定优化特定视觉效果(例如烟雾或细节阴影)能否实现目标帧速率。

我们建议使用英特尔 GPA 确定有助于实现目标的可能改进,并且将这些改进应用到游戏代码之后,你应当验证它们是否实现了预期的性能改进。为此,你需要做两件事:首先,重新运行英特尔 GPA 和新代码库,确保视觉和性能变化表现出了预期的改进效果;其次,重新使用英特尔 GPA 分析游戏,找出其它“热点”,进一步分析和优化游戏性能。

常见但成功率较低的减少瓶颈的方法是,改变一个前期渲染阶段的负载或方法,看看这种改变能否给后期的渲染负载带来正面影响,或者是否会把瓶颈问题转移到后期阶段。本文介绍了一些更有效的方法,使用英特尔 GPA 系统分析器和英特尔 GPA 帧分析器确定和解决游戏瓶颈,并举例说明了如何在渲染管线的不同阶段使用英特尔 GPA。对于你的所有游戏改进目标,我们相信,英特尔 GPA 将成为一个不可或缺的游戏分析和优化工具。

1.1 性能分析的复杂性

图形渲染管线的复杂性以及多个渲染阶段出现瓶颈的可能性,使游戏性能优化成为了一项严峻的挑战:

  1. 每个游戏场景的渲染都会带来不同的瓶颈,而且各种对象在不同场景中可能会遇到不同的瓶颈。例如,一个使用多个复杂纹理渲染的场景可能会因为内存访问延迟而遭遇瓶颈,尤其是当这些纹理没有缓存在图形处理器单元(GPU)内存中时。使用像素着色器渲染的对象可能会在处理上一批来自像素着色器的像素时遭遇瓶颈,因为在几何图形从光栅器输出时,系统正在渲染上一批像素。最后,使用 Microsoft DirectX*(DX) 锁和图形处理器单元(GPU)查询或许可以将瓶颈从渲染管线的一个阶段转移到另一个阶段。
  2. 因为系统最底层缺乏精确的测量方法,所以这一层的瓶颈更难确定;例如通过 DirectX 或 OpenGL* 规划显卡的视频 RAM。
  3. 图形处理管线(GPPL)可以在 3D 几何渲染管线的不同功能阶段渲染游戏场景和对象。
    • 应用阶段在软件中实施。这一阶段的常见瓶颈与 CPU 使用有关,可以通过以下三种方法解决:使用编译器的内建优化功能;通过多线程实施并行性;或者将一些面向图形的功能转移到 GPU。
    • 几何阶段可以在软件和/或硬件中实施,执行多项式函数、顶点运算、转换和裁剪。这一阶段的常见瓶颈与执行转换和裁剪所需的处理时间有关。解决方法是针对各个场景使用适当的细化分层,或者通过其它方法裁剪不能改善帧视觉质量的普通图元。
    • 光栅阶段在软件和/或硬件中实施,可能会遇到填充或插值瓶颈。这些瓶颈通常使用上文 3b 部分介绍的方法解决。
    • 像素着色和纹理访问阶段在软件和/或硬件中实施,与光栅阶段相互影响。常见瓶颈包括复杂像素着色器、复杂纹理和光线跟踪。要解决这些瓶颈问题,需要想办法降低这些特性的整体复杂性,同时维持出色的视觉质量,为用户带来身临其境般的游戏体验。
    • 帧缓冲阶段是为画面显示做最后的准备,在软件和/或硬件中实施。这一阶段的瓶颈通常出现在模板阴影和 alpha 混合等运算的片段重关联和帧缓冲内存访问中。另外,你需要在渲染时间和视觉质量之间权衡取舍。这是一项有些困难但却能够完成的工作。你可以使用英特尔 GPA 实验选择分析和优化,看看它们如何改善游戏性能。

英特尔 GPA 系统分析器和英特尔 GPA 帧分析器

英特尔 GPA 系统分析器可以帮助你确定和隔离四类主要硬件的问题:CPU、GPU、总线和内存(CGBM)。英特尔 GPA 帧分析器是一个深入的帧分析实用程序,用于研究帧速率问题以及从多个方面分析帧绘制复杂性。

系统分析器通过一个交互的实时图形用户界面(GUI)显示 CPU 和 GPU 的游戏性能指标。通过 GUI,你可以选择 DirectX 层覆盖,调用简单像素着色器,禁用驱动和/或硬件,观察你的游戏需要占用大量的 CPU 资源还是 GPU 资源。然后,你可以做一些假设性实验,确定游戏性能瓶颈主要出现在哪些渲染阶段。如果系统分析器显示你的游戏需要占用大量 CPU 资源,请使用英特尔® 专业版编译器的内建优化特性进一步优化游戏代码,并使用英特尔® Parallel Advisor 或英特尔® VTune™ 性能分析器等英特尔性能优化产品确定实施并行性的机会。

帧分析器可以在帧层、区域层和绘制调用层执行分析。它的特性包括绘制调用柱状图可视化、场景概览、渲染目标查看器以及一套丰富的实验。你可以使用简单像素着色器、简化的 2x2 纹理、用于检查像素渲染时间的 1x1 裁剪矩形(scissor rectangle)以及选择性纹理和着色器控制,去除游戏渲染流程的某些部分,观察性能变化。

特定的英特尔 GPA 特性也可用于调试游戏。例如,系统分析器和帧分析器的线框覆盖模式可以让你检查彼此重叠的场景对象,从几何学角度看看它们的绘制是否正确,并且帮助你确定哪些对象更适合用简化的几何学进行渲染。帧分析器可以帮助你检查各个帧内的 DirectX 调用顺序,动态修改 DirectX 状态,以便在不更改代码的情况下查看 DirectX 调用效果。

如果在 GPU 中发现性能瓶颈,你可以使用帧分析器深入分析单个图形帧,找出纹理带宽中的具体渲染问题、像素着色器性能瓶颈、细化分层(LoD)问题以及渲染管线中各个部分的其它瓶颈。每完成一次尝试性调整,你都可以实时查看渲染时间和视觉质量的改进效果。

本文其它部分重点介绍了使用英特尔 GPA 工具分析游戏和其它图形应用在英特尔核芯显卡上的实际性能的方法。

1.3 使用英特尔 GPA 分析游戏性能概述



2. 系统分析方法

为寻找游戏性能瓶颈,我们首先要了解系统配置。

2.1 CPU、GPU、总线和内存(CGBM)域分析

游戏渲染负载分布于四个主域:CPU、GPU、总线和内存(CGBM)。你可以使用英特尔 GPA 中的 CGBM 方法在各个域中寻找瓶颈。

  1. CPU 瓶颈:: 系统分析器提供了一组有关 CPU 利用率的性能计数器。平均 CPU 利用率越接近 100%,越有可能出现 CPU 瓶颈。甚至在平均 CPU 利用率较低的情况下,CPU 访问频率也会导致高 CPU 接触率(例如大约 100%),造成 CPU 瓶颈和不稳定或不均衡的 CPU 负载。使用 2.2 部分描述的“禁用驱动”测试;如果帧速率不增加,说明游戏需要占用大量 CPU 资源。使用编译器内建的优化特性和通过多线程实施并行性,可以解决 CPU 瓶颈问题。英特尔的优化编译器装配于英特尔® C++ 编译器专业版英特尔® Parallel Studio产品。英特尔® 线程构建模块(英特尔® TBB)是一个函数库,可以提供一种丰富、完整的在 C++ 程序中表达并行性的方法。有了它,你无需成为线程专家,即可充分利用多核处理器性能。另外,这些编译器还全面支持OpenMP*线程技术。

    游戏开发人员需要利用分析工具测量一段时间内的游戏性能,然后快速、轻松地解决瓶颈问题以及可能会妨碍游戏性能的其它问题。为高效完成这项工作,开发人员必须能够将性能重新映射到特定的游戏引擎环境。最新的英特尔 GPA 3.0 包含一个支持这种环境分析的跟踪基础设施。

    英特尔 GPA 3.0 带有应用编程接口(API),可以让开发人员在他们的游戏引擎中添加若干行跟踪代码。添加跟踪代码和重新编译游戏之后,开发人员可以使用英特尔 GPA 3.0 平台视图工具,根据引擎中添加跟踪代码的区域获取特定环境下的性能分析。按照这种方式将性能映射到特定的游戏环境,开发人员能够更轻松、更准确地确定瓶颈问题,并尝试做一些变更来解决这些问题。
  2. GPU 瓶颈:要评估 GPU 处理中出现瓶颈的可能性,请使用系统分析器中的“禁用硬件”覆盖模式,评估删除全部 GPU 相关工作负载所产生的影响。如果系统分析器显示游戏帧速率增加,说明这就是 GPU 瓶颈的根源。本文的 2.2、2.3 以及第 3 部分详细描述了确定和解决各类 GPU 瓶颈问题的方法。
  3. 总线带宽瓶颈:集成显卡的显存大部分都在系统内存中,因此系统内存和 GPU 之间的总线带宽可能存在瓶颈。使用系统分析器中的系统内存整体带宽指标,查看当前带宽在平台最大带宽中所占的比重。根据当前的设备驱动技术,平台可维持的实际最大总线带宽是带宽理论峰值的 65% 到 70%。虽然游戏开发人员不能直接解决总线带宽瓶颈问题,但是本文中减少 GPU 负载的方法可以改善可用总线带宽的使用情况。

    峰值双倍数据速率带宽取决于具体的系统配置,因此,请访问 http://www.intel.com/Products/Desktop/Chipsets/,查看详细的系统配置,了解峰值带宽以及你在游戏中是否充分利用了这些带宽。实际上,系统的处理器前端总线(FSB)频率越高、处理器乘数值越高、通道越多,渲染速度就会越快。请注意,英特尔® 酷睿™ 微架构采用的是英特尔® 快速通道互连链路而不是 FSB,因此,系统运行频率更高,而且是同时双向运行。英特尔® 快速通道互连链路应当可以改善目前大多数游戏中的多通道渲染性能。
  4. 内存瓶颈:使用Microsoft* Perfmon*工具确定可能因内存分页增加造成瓶颈问题的进程。检查代码,确保尽快释放内存资源,增加对先前分配内存的重复使用,尽可能减少纹理数量,降低纹理复杂性(参见本文“实验”部分的实验 3.4.2、 3.4.3、3.4.4 和 3.4.5)。

2.2 负载分布分析
使用系统分析器中的状态覆盖模式,观察渲染管线各阶段的负载分布情况(图 1)。

  1. 禁用驱动模式:使用这种覆盖模式删除显卡驱动和 GPU 负载,评估应用的 CPU 利用率对整体帧速率产生的影响。另外,该模式还可以让你删除驱动和显卡负载,同时保持其它任何配置不变,观察游戏在系统上的最佳理论性能。
  2. 禁用硬件模式:使用这种覆盖模式删除 GPU 负载,观察游戏需要占用大量 GPU 资源还是 CPU 资源。如果在这种模式下发现帧速率有明显增加,说明游戏需要占用大量 GPU 资源。本文 2.3 部分和第 3 部分可以帮助你解决游戏大量占用 GPU 资源的问题。通过比较游戏在该模式与前一个模式下的性能,你可以确定是驱动还是 API 存在瓶颈。
  3. 1X1 Scissor Rect:在基于英特尔核芯显卡的系统上,这种覆盖模式可以在像素着色器运行之后和像素值写入渲染目标之前,弃用所有的像素,将像素处理减少到平均每绘制调用一个像素。如果帧速率在该模式下有明显增加,说明像素填充率是瓶颈。第 3 部分介绍的几个实验可以帮助你解决像素处理瓶颈。

图 1:渲染过程中的负载分布


系统分析器可以测量帧速率和帧时间,确定速度减慢和瓶颈究竟与 CPU、GPU 有关,还是与 Microsoft DirectX* (DX) 运行时运算有关。在系统分析器中启用各个覆盖模式,观察相应的帧时间,你可以计算负载分布图表中的四个时间段(T1、T2、T3、T4)。在负载分布图表中标记你的目标帧时间,将其与 T1/T2/T3/T4 进行比较,判断仅优化显卡负载(例如选择不同的着色器)能否实现目标性能。如果不能,你可能需要优化应用层代码。然后,开始瓶颈分析,做我们介绍的各个实验,在完成各个实验或一套相关实验之后,重新查看游戏的帧速率和视觉质量。

从系统分析器负载分布图表来看,你可以初步得出以下几个结论。请注意,我们按照 T4、T3、T2、T1 的顺序加以描述,因为这是优化显卡管线性能的一般分析顺序。我们建议从显卡管线的后端开始往前端查找瓶颈,分析和优化游戏性能。

  • T4:当英特尔核芯显卡裁剪后进程时间大于零时,说明像素处理过程中存在瓶颈。参考 3.4 部分,了解几个可以解决像素处理瓶颈的实验。
  • T3:当英特尔核芯显卡裁剪前进程时间较高时,说明顶点处理存在瓶颈。目标是看到裁剪前进程时间接近零。通过降低对象网格的网络 LoD 复杂性,使用带有简单转换和照明(T&L)算法的顶点着色器,以及运用遮挡剔除查询消除隐藏绘制,可以解决顶点处理瓶颈。
  • T2:当英特尔核芯显卡驱动时间占用大部分的整个帧时间时,请调查 DirectX API 调用中的潜在效率低下问题,以及应用是否正在通过显卡驱动将大量不必要的数据拷贝到 GPU。参考 2.3、3.1 和 3.3 部分,了解解决 DirectX 调用相关瓶颈的方法。
  • T1:评估应用层游戏帧速率上限。当帧速率低于相同类型的其它游戏帧速率时,考虑确定实施并行性的机会,优化应用代码,包括 DirectX 中间件。使用英特尔® Parallel Advisor 或英特尔® Vtune 性能分析器分析实施并行性的热点,然后使用英特尔 TBB 或其它线程技术对应用代码进行并行化。

2.3 DirectX 分析
系统分析器提供了一组关于 DirectX 的性能计数器(图 2),可以计算 DirectX 调用消耗的时间,以及分析 DirectX 调用对渲染管线后续阶段的性能影响。

  • DirectX 绘制调用会产生一定的性能开销,显著增加应用在驱动上消耗的时间,尤其是当各个 DirectX 调用包含的图元相对较少时。观察每帧 DX 绘制调用计算器 的值,把它与类似游戏的平均值进行比较。
  • 频繁的 DirectX 状态改变会产生很大的性能开销。通过每帧 DX 状态变更计数器和每帧 DX 绘制调用计数器,可以算出平均每个绘制调用的 DX 状态变化次数,把它与类似游戏的平均值进行比较,然后使用 3.1 和 3.3 部分介绍的方法,确定 DirectX 调用减少情况。
  • DirectX 锁通常会使 GPU 等待 CPU。使用每帧 DX 锁计数器和帧时间 DX 锁百分比计数器,确定代码中 DX 锁对性能产生的影响以及任何被删除的 DX 锁。
  • 系统分析器可以帮助你确定游戏中出现挂结(hitching)的帧,也就是在游戏人物移动或者偶尔静止时,每隔几秒就会出现轻微冻结或中断。如果你发现有挂结,请查看频繁出现峰值的图表,查找发生挂结的帧。通过减少游戏使用的纹理,关闭抗锯齿处理,确保使用最新的显卡驱动,可以解决挂结问题。你可能需要查看不同采样设置的图表,看看何时发生挂结或跳跃。

图 2:DirectX 计数器采样

3. 单帧性能分析方法

使用以下方法分析任何单帧出现帧速率缓慢的根源。

3.1 确定耗时的绘制调用
分析绘制调用是改善游戏性能的关键,因为绘制是相对耗时的运算,需要占用大部分游戏 GPU 时间。使用帧分析器可以按照“GPU 持续时间”对所有绘制调用进行排序,然后研究最耗时的绘制调用(图 3);也就是说,检查在整个帧时间内所占比重最大的绘制调用。需要注意的是,尽管某个绘制调用消耗的 GPU 时间可能最长,但是它在整个帧时间中的比重可能很小;因此,优化单个耗时的绘制调用可能不会显著改善帧速率。

真正需要关注的是某一批同类的绘制调用,例如使用相同纹理或相同像素着色器的调用,以及渲染同类对象(地形、植被等)的调用。如果帧分析器显示它们在整个帧时间中的比重很大,那么优化这批绘制调用能带来显著的性能提升。在帧分析器的“着色器”标签上,右键点击与指定绘制调用相关的着色器,选择一批使用相同着色器的绘制调用(图 3)。在“纹理”标签上,右键点击与指定绘制调用相关的纹理,选择使用相同纹理的一批绘制调用。确定了几个或几批耗时的绘制调用后,使用 3.3 部分(绘制批处理尺寸)、3.4 部分(像素、着色器、纹理等实验)、3.5 部分(绘制顺序)和 3.6 部分(渲染目标变更)描述的方法和实验,深入分析这些调用。

3.2 检查指定 erg 的帧时间百分比
通常,你需要了解游戏在某个视觉效果上的耗时在整个帧时间中占多大比重,例如人物渲染或 HDR(高动态 光照渲染)色调映射。在图 3 中,你可以看到指定 erg 所需的时间。Erg 是一个功或能量单位:厘米-克-秒,1 erg 相当于 10 到 7 焦耳。如果时间太长,请考虑选择一个更加优化的效果,甚至针对某些类别的设备禁用耗时的效果。

图 3:确定最耗时的绘制调用和一批相关调用



3.3 分析绘制调用的图元批处理尺寸

将适量的图元调用批处理成为一个绘制调用,可以最大限度缩短 DirectX 绘制调用所需的时间。对于英特尔核芯显卡,我们建议的图元调用批处理尺寸在 200 到 1000 之间。使用帧分析器的Prim Count(图 4)分析图元批处理尺寸较小的绘制调用,考虑将它们整合成批处理尺寸较大的绘制调用。观察屏幕像素覆盖率和其对象的细节分层,评估图元批处理尺寸较大的绘制调用。简化细节分层(LoD)的方法包括管理着色器以控制像素复杂性(参见第 3 部分介绍的像素相关实验),使用连续细节分层(CLoD)优化多边形网格,使用分级细节分层(HLoD)对场景中的对象进行分级聚合。适当的时候,考虑使用纹理,而不是渲染各个图元。

图 4:图元数和顶点/像素处理持续时间



3.4 做实验

英特尔 GPA 可以让你使用系统分析器中的假设性实验,分析游戏在普通环境中的性能表现,从较高的层面上判断游戏性能瓶颈集中出现在什么地方。通过实验进行特定类型的渲染,可以帮助你寻找瓶颈,了解在不更改显卡管线各部分代码的情况下优化游戏需要什么。在确定应当作出哪些更改之后,你需要修改代码,验证这些变更能否带来预期的性能改进和视觉质量提升。

3.4.1 顶点处理实验和像素处理实验
当选择了一批待优化的绘制调用后,首先观察和比较“详情”标签中的“顶点着色器持续时间”和“像素着色器持续时间”(图 4),判断游戏瓶颈主要在顶点处理中还是像素处理中。在帧分析器的 Erg 柱状图中,“详情”标签和“着色器”标签分别在 GPU 分解图部分和针对所有绘制调用显示了每绘制调用的几何着色器(GS)持续时间,可以帮助你分析瓶颈主要出现在哪里。

通过降低对象网格的网络 LoD 复杂性,使用带有简单转换和照明(T&L)算法的顶点着色器(VS),以及运用遮挡剔除查询消除隐藏绘制,可以解决顶点处理瓶颈。对于像素着色器(PS)瓶颈,请尝试 3.4 部分介绍的一些像素相关实验。

图 5:带样本显示的英特尔 GPA 帧分析器实验窗口



3.4.2 像素处理纹理分析实验

从帧分析器的“实验”标签中选择“2x2 纹理”实验,评估缩小纹理尺寸所产生的影响。“2x2 纹理”实验用完全位于纹理高速缓存中的英特尔 GPA 默认简单纹理代替游戏的原始纹理访问,消除从内存访问纹理时遇到的带宽和延迟问题。如果这个实验可以显著缩短 GPU 时间,纹理总数和/或整体纹理复杂性很可能就是瓶颈。继续观察“纹理”标签中的纹理列表,评估场景中使用的各个纹理的尺寸和访问频率,以及它们对帧速率和视觉质量的影响。

3.4.3 纹理 Clamp to MIP 实验
Clamp to MIP实验可以评估减少纹理细节对帧速率和相应视觉质量产生的影响(图 6)。从场景使用的纹理列表中选择一个被频繁访问的大尺寸纹理,调高 MIP 级别使纹理尺寸减少,观察 GPU 时间和“普通”模式下“渲染目标查看器”的变化。如果发现 GPU 时间明显缩短,而视觉质量变化不大,请考虑针对该场景减少纹理分辨率。

图 6:改变纹理 Clamp to MIP 的实验


3.4.4 alpha 测试实验
在大多数情况下,当“Clamp to MIP”和“2x2 纹理”实验大幅提高性能时,说明瓶颈在于纹理尺寸。但也有例外情况。我们曾经观察到这样一个案例,做“2x2 纹理”实验时,GPU 时间明显减少,这说明瓶颈出现在纹理尺寸上。然而,调高 MIP 等级却不会减少 GPU 时间。这两个实验不仅改变纹理尺寸,还会缩小纹理色域(包括 alpha 值),因此改变游戏的 alpha 测试负载。

然后,我们在“状态”标签试验中禁用了 alpha 测试(图 7),发现帧速率有明显增加。为验证瓶颈根源在于 alpha 测试而非纹理尺寸,请尝试禁用 alpha 测试,或者调整 alpha 参考值。当使用透明半透明效果(例如叶纹理)渲染凹形对象时,alpha 测试非常重要。

图 7:改变 DX 状态的实验



3.4.5 过滤算法实验

为评估纹理采样器使用的过滤算法是不是瓶颈,你可以尝试用一个更简单的过滤算法来代替该算法。例如,各向异性过滤(AF)需要更多的内存带宽,是一个计算密集型算法,尤其是在各向异性过滤等级较高时。切记,AF 是一种在相对相机处于倾斜视角的表面上改善纹理画面质量的方法,这些表面上的纹理投影看上去不是直角。它在去除混叠效果的同时,也可以在极端视角下减少模糊,这一点不同于双线和三线过滤。观察你正在使用的纹理,确定不能通过 AF 得以改善的纹理,例如低频光效图纹理。

3.4.6 分析渲染目标使用情况
如果你使用屏幕外渲染目标,则需要了解它们如何影响游戏性能。高分辨率渲染目标需要更多内存,从而增加像素工作负载和填充率。由于广泛的纹理高速缓存缺失,从高分辨率渲染目标提取纹理通常是一个瓶颈。后处理管线(例如 HDR 效果)中常用的浮点渲染目标运行起来比其它格式慢。因此,请在分析性能时,观察活动渲染目标列表,尤其是它们的尺寸和格式(图 7)。使用最基本的尺寸和格式总能让你获益匪浅。

3.4.7 分析 API 日志
帧分析器可以让你观察与帧中各绘制调用相关的 Direct 3D (D3D) API 调用列表,包括顶点/索引流设置、状态/采样器状态变更,以及常量和像素、顶点与几何着色器设置(图 8)。你可以使用该日志分析 API 使用情况,减少驱动/CPU 瓶颈。例如,把具有类似渲染状态的图元和带有连续绘制调用的着色器放在一起,而不是不断更改参数,进而更改图形状态。另外,你也可以利用 API 日志寻找代码中的重复调用。最后,你不需要检查所有调用的所有 erg,而是利用该特性检查那些处理时间最长的 erg。

图 8:分析 API 日志



3.4.8 分析着色器代码

如果你已经确定具体某个绘制调用在像素或顶点着色器方面受限,请使用“着色器”标签(图 9)检查着色器代码。如果你编译的是运行时着色器,你可以看看 DX 着色汇编器代码和 HLSL(高级着色器语言)列表。具体来讲,看看指令个数和着色器常量个数。

图 9:分析着色器代码



3.4.9 简单像素着色器实验

帧分析器中的“简单像素着色器”实验(图 5)用一个非常简单的像素着色器替换应用原有的像素着色器,用默认颜色渲染像素,所以没有纹理访问和像素着色器计算开销。无论你在游戏中使用可编程渲染管线还是固定渲染管线,该实验都可以让你确定哪部分渲染时间用在了指定 erg 的着色器中。

如果简单像素着色器明显减少了 GPU 时间,则要重点观察着色器的复杂性。此时,使用帧分析器的“着色器”标签显示源代码或者指定绘制调用使用的效果文件(.fx)汇编器代码。确定耗时的着色器,也就是算法有大量指令和大量注册表的着色器。比较着色器函数中定义的 DX 状态值(图 7)和帧分析器中的当前 DX 状态,从而把绘制调用关联到在帧中使用的着色器函数。简化着色器复杂性的方法有很多,例如减少渲染深度,利用 Early-Z 裁剪,使用低精确度,或者将片段工作迁移到顶点着色器。

3.4.10 像素过度绘制实验
启用“渲染目标查看器”的“过度绘制”模式(图 5),观察任何屏幕像素的填充历史,看看渲染到某个像素的绘制调用是否过多。要解决过度绘制问题,你需要通过“禁用 Erg”实验(图 5)评估减少不必要绘制调用的优势,或者启用 Early-Z 裁剪。你可以灵活组合多种覆盖模式和状态修改,更加深入的分析游戏。另外,你也可以查看渲染到某个像素的具体 erg 的像素历史,看看渲染是否经过优化(例如,是否发生 Z 裁剪)(图 10)。

图 10:查看像素历史,确定是否有过度绘制



3.4.11 了解帧中的过度绘制

如果你发现帧中有大量的过度绘制,或者注意到有许多 erg 渲染到像素,而且没有轻微裁剪,你可能想详细检查几何屏幕中被这些调用渲染的区域。你可以在“指定 Erg”区域(图 5)看到这些信息。你也可以隐藏其它调用,查找 erg 的大部分像素区域被后续绘制调用隐藏和覆盖的情况。如果这些调用发生在指定 erg 之后,你的游戏则不能利用轻微的 Z 裁剪,因此,请考虑改变算法的渲染顺序,尽量避免使用不同绘制调用多次全面渲染各个像素。


3.5 了解英特尔® 核芯显卡硬件指标

从 3.0 版开始,英特尔 GPA 支持最新英特尔集成显卡芯片组(首先是支持英特尔核芯显卡的芯片组)的其它硬件指标。在英特尔 GPA 系统分析器 GPU 类别下的“指标树”中列出了这些新指标(图 11)。你只需将指标名称拖拽到系统分析器窗口的右侧,即可查看任何一个指标的实时图表。对于各个指标,显示了整个帧的总值。

图 11. 系统分析器中的新硬件指标


新指标在英特尔 GPA 帧分析器的各个 Erg“详情”标签中也有列出(图 12)。使用英特尔 GPA 和旧版英特尔显卡芯片组或非英特尔 GPU 时,“详情”标签上只显示三个指标--GPU 持续时间、顶点着色器持续时间像素着色器持续时间。在英特尔核芯显卡芯片组上运行时,将显示 24 个新硬件指标。关于新指标和英特尔集成显卡结构图的详细描述,请参考英特尔 GPA 文档附录 A。

图 12. 帧分析器中的新硬件指标


新指标在英特尔 GPA 帧分析器的各个 Erg“详情”标签中也有列出(图 12)。当你通过修改渲染或状态、编辑着色器和纹理设置、应用“实验”标签中的实验等方法更改帧时,系统分析器会更新指标,体现变化带来的影响,显示与变化相关的新旧值。发生改变的指标以彩色显示,便于你查看变化效果(图 13)。

图 13. 以彩色显示的帧分析器硬件指标变更


最有利于改善游戏性能的指标与 GPU 后端有关。GPU 后端是一个执行单元阵列,负责处理不同类型的线程:像素、顶点、几何着色器线程、裁剪或媒体线程。“GPU 后端活跃”、“GPU 后端繁忙”、“GPU 后端停住” 指标可以显示执行单元将百分之几的 erg 持续时间用在了线程处理上。

如果“GPU 后端停住” 百分比较高,你需要查看“GPU 后端在样本上停住” 、“GPU 后端在 Mathbox 上停住”、“GPU 后端在数据端口停住”指标,找到停住位置。

百分比最高的采样器停住说明着色器上的纹理提取指令超载,或者有大量的纹理高速缓存缺失。为减少停住,请尽量减少着色器中的纹理提取指令,缩小纹理尺寸,优化纹理提取模式,提高纹理高速缓存效率。观察“采样器吞吐量”指标,看看纹理请求从内存读取的字节数,了解纹理高速缓存缺失程度。“纹理采样”指标可以显示从纹理单元抽取的纹理数量。通过评估这两项指标,你可以准确计算出纹理高速缓存缺失比重。如果你发现纹理高速缓存缺失,请尝试改变纹理提取内核,更加高效地使用高速缓存。

Mathbox是一个专门处理 sin/cos、指数和平方根等复杂数学函数的处理单元。如果大多数停住与 Mathbox 有关,说明你的游戏很可能正在使用包含大量复杂数学指令的着色器。你需要尽可能简化游戏着色器使用的数学指令,混合纹理和数学指令,减少延迟。纹理查找表(LUT)不是最大限度减少 Mathbox 停住的最佳方法,因为纹理提取延迟通常高于 Mathbox 运算延迟。

“数据端口”是一个提供内存读写访问的功能单元。“数据端口”停住通常与着色器依赖大量着色器常量或内存读取有关,例如在 DX10 计算着色器中。

“顶点数”、“图元数”“顶点着色器调用数”指标可以说明你的几何图形针对转换后高速缓存在多大程度上进行了优化。“顶点数”指的是进入管线的顶点总数,“图元数”指的是渲染的图元总数,“顶点着色器调用数”指的是顶点着色器内核执行总数。例如,如果你渲染 4 个顶点中的一个,结果会得到 2 个三角形(图元数 = 2),总共需要处理 6 个顶点(顶点数 = 6),顶点着色器将被调用 4 次(顶点着色器调用 = 4)。

“裁剪调用数”、“裁剪后图元数”、“未被剔除多边形”指标与几何剔除和裁剪有关。裁剪调用数等于需要裁剪的图元个数。例如,如果你在启用“裁剪”功能的情况下渲染 100 个三角形,那么裁剪调用数等于 100。如果禁用“裁剪”功能,那么裁剪调用数就等于 0。裁剪后图元数显示有多少图元未被裁剪。未被剔除多边形指的是未被剔除背面(如果是正面剔除,则是正面)的多边形个数。

“几何着色后图元数”指标显示有多少图元是在几何着色阶段创建的,如果你的游戏使用几何着色器创建不同数量的图元,这个指标则非常有用。

“像素着色器调用数”、“像素着色器线程”和“被渲染像素”指标显示了指定 erg 的 Early-Z 剔除有效性。像素着色器线程运行在 8 个或 16 个像素上,像素线程数越少,帧速率越高。如果被渲染的像素个数明显低于调用数,就会有许多像素被 Z 测试剔除,那么 Early-Z 剔除将对该调用无效。如果你发现这种情况,请尝试更改渲染顺序,改善 Early-Z 像素裁剪。

渲染目标 SubSpans 写入个数指的是 4 个像素中有几个被写入渲染目标。写入个数越多,说明填充率越高,但是这会降低渲染性能。

如果你的游戏运行在英特尔核芯显卡硬件之上,请使用英特尔 GPA 查看平均每帧像素数。如果像素数较高,请使用帧分析器确定哪些绘制调用导致大量的像素被渲染,然后进行优化。

使用“渲染目标视图”下的过度绘制可视化模式查找热点,然后结合像素历史和过度绘制分析,查看引起热点的所有绘制调用。接下来,选择关键绘制调用,查看被渲染像素的相关指标,确定需要优化哪些绘制调用。


3.6 分析绘制场景对象的次序

绘制场景对象的次序通常会带来许多性能改进机会。把具有类似状态和/或其它图形资源(例如纹理)的绘制调用放在一起,可以减少图形渲染管线中的开销;从前向后渲染能大大减少像素过度绘制和渲染时间。如果游戏没有源代码可用,请在帧分析器中依次选择绘制调用,观察渲染目标的改变,可以获得场景对象的绘制次序。分析整个绘制次序时,要关注以下几个方面的问题:

  • 游戏绘制次序是否有利于提高性能?把使用相同渲染状态、着色器或耗时纹理按顺序依次执行的绘制调用放在一起,可以减少或避免相对耗时的图形状态更改开销。
  • 游戏使用的是批处理尺寸较大的绘制调用,很难批处理中各个绘制调用的 GPU 时间?如果是这样,那么使用 3.1 部分介绍的方法则不能确定优化机会,而是必须分析绘制调用次序才能发现优化机会。
  • 游戏采用了适当的优化方法,可以实现最佳性能吗?例如,对于 Early-Z 测试,显卡可以维护写入屏幕的各个像素的深度记录。如果新对象更加远离已经针对该像素渲染的对象,那么新像素的渲染时间会被去除,这对复杂像素着色器来说尤为重要。Early-Z 裁剪技术适用于屏幕上有多个像素的对象,以及使用复杂像素着色器的对象;然而,该方法需要额外的渲染通道来构建场景深度。使用帧分析器观察到的绘制次序可以说明是否采用了这种方法。如果游戏场景不适合采用 Early-Z 裁剪,这种方法可能会降低游戏性能。
  • 有冗余的绘制调用吗?避免绘制隐藏对象和重复渲染场景对象,查看场景剔除算法,判断能否调试。
  • 切记,如果你重新排列场景中的对象绘制次序,你还需要重新评估场景中是否有像素过度绘制,然后寻找任何新机会,去处不必要的绘制调用或启用 Early-Z 裁剪。


3.7 观察渲染目标的变化

每执行完一套优化或实验之后,观察渲染目标的帧速率、帧时间和视觉质量。比较渲染目标的变化与相关绘制调用开销,可以发现许多关于渲染质量和效果的重要信息。帧分析器可以提供以下功能,帮助你全面分析游戏场景渲染:

  • 选择“正常”选项,观察指定绘制调用在画面中表现出来的可见变化。
  • 选择“突出显示”选项,观察指定绘制调用的像素覆盖范围;删除任何冗余的或隐藏的绘制调用。
  • 选择“线框”或“突出线框”选项,观察指定绘制调用的对象网格和顶点复杂性(与顶点处理负载有关)。
  • 选择“弹出”选项,突出显示不可见的对象,验证它们是不是被其它对象遮挡住了,然后删除其它对象的绘制调用。
  • 启用“擦洗”(Scrub)模式,观察各指定绘制调用的每个屏幕变化。

结论

优化游戏在集成显卡上的性能,可以增加游戏或图形应用的受欢迎度和销量。本文介绍了一些实际性能分析方法,使用英特尔® 图形性能分析器优化游戏在英特尔® 核芯显卡上的实际性能。


参考

  1. 英特尔® 图形性能分析器主页:/zh-cn/articles/intel-graphics-performance-analyzers 英文版/en-us/articles/intel-gpa
  2. CPU Z: http://www.cpuid.com/cpuz.php
  3. 英特尔® GPA 快速入门指南:/en-us/
  4. 英特尔® Vtune 性能分析器:/zh-cn/intel-vtune/
  5. 案例研究:使用英特尔® GPA 优化金山软件《剑侠情缘三》游戏的性能: /en-us/articles/optimizing-kingsofts-jx3-online-using-intel-graphics-performance-analyzers
  6. 英特尔® 核芯显卡主页:http://www.intel.com/p/zh_CN/support/highlights/graphics/hdgraphics
  7. 英特尔集成显卡信息页:/en-us/articles/integrated-graphics
  8. 英特尔® 编译器专业版主页:/zh-cn/articles/intel-compilers/
  9. 英特尔® 线程构建模块主页: /zh-cn/intel-tbb/
  10. 英特尔® Parallel Studio 主页:/zh-cn/intel-parallel-studio-home/
  11. 用于台式机的英特尔® 芯片组技术主页:http://www.intel.com/Products/Desktop/Chipsets/
  12. OpenMP* .org 网站: http://openmp.org/wp/

作者简介

郭胜是英特尔开发者关系部门的应用工程师,主要负责为游戏独立软件开发商(ISV)提供英特尔技术资源和性能优化服务。他拥有南京大学计算机硕士学位,擅长实时 3D 图形应用的软件设计、编程以及性能优化。

Philipp Gerasimov 是 VCSD/SSG 英特尔高级视觉计算事业部的技术咨询工程师。Philipp 负责与英特尔以及独立软件厂商(ISV)的不同开发部门就英特尔 GPA 支持和未来图形架构开发开展合作。他也经常参加游戏开发和计算机图形会议。他参与过许多现代计算机游戏的性能优化工作,例如《孤岛危机》*、《恐怖杀手 2》*、《狂野西部》* 和《太平洋战机》*。

Neal 是英特尔软件与服务事业部(SSG)高级视觉计算部门的高级技术咨询工程师。Neal 负责与客户密切合作,利用英特尔的图形产品帮助客户取得成功。Neal 负责为广泛的细分市场中的图形产品提供产品开发与产品支持,例如 MCAD、GIS、EDA 和有限元素分析(Finite Element Analysis)。另外,Neal 的另一项职责是参加各种标准委员会,帮助定义图形标准。Neal 毕业于美国布朗大学应用数学/计算机专业(专修计算机图形),获得学士学位和硕士学位。

Bonnie Aona 现在是英特尔软件与服务事业部(SSG)编译器和语言部门的软件工程师,负责复杂应用的优化工作,确保应用在目标环境中实现高性能和最佳并行性。她的工作是利用复杂的技术分析和软件设计,为计算机图形、实时系统、科学研究、汽车制造、电子商务、航天以及医疗保健等行业提供高性能应用。她毕业于加利福尼亚大学戴维斯分校电子与计算机工程专业,获得硕士学位。

有关编译器优化的更完整信息,请参阅优化通知