3816dc1596c0ed2304b60a7ea85aedf8
WWDC20 {10603} 使用图形处理器计数器优化 Metal app 和游戏

前言

本文内容基于 Optimize Metal apps and games with GPU counters 整理。
本 Session 讲的是如何通过 GPU 性能计数器优化游戏和 App 性能,了解最新苹果 GPU 的架构和介绍它的性能标准。

概况

首先会讲 GPU 和图形处理器计数器,然后讲 几组 GPU 性能计数器。
我们会讲:

  1. 性能限制
  2. 内存带宽
  3. 精度
  4. 隐藏消除


首先熟悉一下 Apple GPU 的一些特性:

  1. GPU 是苹果处理器的核心部分之一,运行效率非常高。
  2. 它有自己的内存架构可以和 CPU 共享系统内存。GPU 还有芯片自带的贴图内存,但是没有视频内存。
  3. DRAM 带宽很有限。
  4. GPU 采用了 TBDR 架构。

这是一张 GPU 管线图。渲染管线有两个阶段,贴图和渲染。

贴图阶段

贴图负责处理所有的几何体信息,渲染负责所有的像素处理,着色。

在贴图阶段,GPU 会在整条渲染通道中执行:

  1. 把视图切成一系列的图块。
  2. 着色所有的顶点。
  3. 并且把转换后的图元数据传输给图块。

完成后,GPU 就会单独着色图块,每个 GPU 内存一次至少着色一个图块。

渲染阶段


在渲染阶段,GPU 会在渲染通道对每个图块执行:

  1. 加载。
  2. 光栅化。
  3. 计算所有图元的可视度,着色可见的像素。
  4. 执行存储操作。

这就是为什么我们能把设计做到如此细致的原因,更多的 GPU 内核意味着一次能着色更多的图块。


苹果 GPU 是多核的。每个 GPU 内核都有一个着色核心模块,一个贴纸单元,何有像素后端,还有一个图块内存池。图块内存只是层级的一部分。ALU(逻辑计算单元)和 TPU (张量处理器)都致力于 L1 缓存。所有的 GPU 内核都共享最后一级的缓存,这个缓存也是系统内存 DRAM。

这里先普及下 GPU 有关的一些信息。为了渲染图形帧:

  1. GPU 需要处理多个渲染通道。
  2. 每个通道都会都会在多个 GPU 内核中执行。
  3. GPU 内核也会轮流处理不同的任务,比如着色和纹理处理。
  4. 这些任务都会在不同的硬件单元上执行,比如 ALU 和 TPU。
  5. 单元自身用不同的指标计算也有不同的吞吐量。

我们用FLOPS(每秒浮点运算次数)去度量 ALU 吞吐量,用每秒百万字节数度量 TPU。所以有不同的指标,具体应该用哪个?

GPU 计数器


GPU 计数器会计算 GPU 是如何被使用的,从而帮忙我们发现 GPU 是空闲还是过载,查找性能瓶颈,优化耗时操作。不过有超过150个 GPU 计数器,辨别查找就成了问题,好在 GPU 提供了工具集。

Metal System Trace

instrument 里的 Metal System Trace是用来看性能概况的,可以同时查看 CPU 和 GPU 的时间线。热量和动态系统变化会改变工作量。Metal System Trace 是 instrument 里游戏性能模板的一部分。可以打开 GPU 性能计数器去标记当前帧不同时间点潜在的 GPU 和内存瓶颈。

Metal Debugger

他的作用是:

  1. 用来做深度性能排查。
  2. 可以同时查看 GPU 时间线细节和 Metal API 的使用率。
  3. 工作量不受发热量和动态系统改变影响。


XCode 还支持 GPU 计数器并以编码的粒度去展示他们。每一个绘制操作都会用到这些计数器的很大一部分。XCode 会展示所有的计数器,所以可以很好的关联这些指标,并且帮助你关注那些重要的。

计数器种类

接下来讲不同种类的计数器。首先是性能限制器,因为 GPU 的平行特性,性能限制器显得尤为重要。GPU 会平行地执行一堆工作,包括:计算,内存访问和光栅化。限制计数器会测量多个 GPU 子系统的活动状态,找到正在执行的任务,和找到被卡住的任务。GPU 是有最慢短板的。限制器会帮你指出最慢的地方协助你去调查。

例子

接下来以一个实际游戏例子来学习 Metal System Trace。

为了理解它运行的状态,这里会讲解如何在 instruments 里使用性能限制器。
步骤包括:

打开 instruments 里的 Game Performance.

XCode 连上和选中设备和游戏,长按录制按钮和点击录制选项。

Options for: 选择 Metal Application, 选中 Performance Limiters 和 Shader Timeline, 然后点击录制按钮。

一会结束后就可以按结束按钮。

游戏性能模板手机了当前系统状态的很多信息,我们先只关注 GPU 的信息。打开 A12Z,查看当前的运行状态。

这时候按住 Optional 键拖动就可以缩放查看帧状态。

现在可以看到所有正在运行的命令缓冲区和编码器的时间线,每一帧的颜色编码。

可以看到这个游戏 (Respawnables Heroes)先渲染一个阴影映射表,跟随的是一个看起来可以粗略在顶点和片元着色对分的延迟阶段编码器,不过片元着色器看起来偏长。这里是1.29 ms。主要是受一堆后处理的效果影响。

接着继续看最耗时延迟编码阶段,打开 Fragment 查看新的着色时间线,它会显示在命令编码阶段执行中一定的采样次数下的着色器。

这个细节可以很容易的查看和标识最耗时的着色器,帮助我们理解为什么当前的编码器需要耗费这么多的时间。通过选中 track 和一定的区域,可以看到那些着色器在运行,还有多少采样点和大概的 GPU 时间。

top Created with Sketch.