如何优化代码 Apple的 Metal 图形框架

有多种方法可以优化 Metal 图形代码以获得最佳性能。 以下是如何让您的代码更适合 Metal 框架。

Apple GPU架构

Apple GPU 是基于图块的延迟渲染器 – 也就是说,它们使用两个主要通道:图块和渲染。 整个渲染管线如下图所示。

您可以将这两个阶段视为计算和创建几何图形的阶段,以及处理所有像素渲染的另一个阶段。

在大多数现代 Apple 使用 GPU 软件计算几何形状并将其分解为网格和多边形,然后渲染为基于像素的图像,每帧一个图像。

现代的 Apple GPU 在每个核心中都有特定的子部分,称为着色器、纹理、 Pixel-管理后端和专用磁贴存储。 每个核心在渲染时都会使用这四个区域。

每个帧渲染都使用在多个 GPU 核心上运行的多个通道,每个核心处理多个任务。 一般来说,核心越多,性能越好。

GPU计数器

为了测量该性能,使用了 GPU 计数器。

GPU 计数器跟踪每个 GPU 的利用率并测量每个 GPU 是否完成了足够的工作。 他们还确定性能瓶颈。

最后,GPU 计数器会优化耗时最长的指令以加速性能。

有超过150种 Apple GPU 性能计数器以及全部内容超出了本文的范围。

存在理解所有性能计数器数据的问题。 为此,您可以使用 Xcode 和 Instruments 中内置的 Metal System Trace 和 Metal 调试器。

有四个 Metal GPU 计数器,它们提供了在应用和游戏中优化 Metal 的重要方法。 他们是:

  1. 功率限制器
  2. 内存带宽
  3. 占用
  4. 隐 Surface 距离

性能限制器或限制计数器通过确定正在执行的工作并检测可能阻止或减慢并行执行的延迟来测量多个 GPU 子系统的活动。

现代 GPU 并行(同时)执行数学、内存和光栅化工作。 性能限制器有助于识别降低代码速度的性能瓶颈。

您可以使用 Apple 的 Instruments 应用程序来利用性能限制器来优化您的代码。 Instruments 中有六种不同的功率限制器。

内存带宽计数器

GPU 内存带宽计数器测量 GPU 和系统内存之间的传输。 每当访问缓冲区或纹理时,GPU 都会访问系统内存。

但是,请记住,系统级缓存也可以被触发,这意味着您可能偶尔会注意到内存吞吐量高于实际 DRAM 传输速度的小突发。 这是正常的。

如果您看到内存带宽指示器具有较高的值,则可能意味着传输正在减慢渲染速度。 为了消除这些瓶颈,您可以采取多种措施。

减少内存带宽减慢的一种方法是减少工作数据集的大小。 这可以加快工作速度,因为从系统内存传输的数据更少。

另一种选择是仅加载当前渲染通道所需的数据并仅保存未来渲染通道所需的数据。 这也减少了总体数据大小。

您还可以使用块纹理压缩 (ASTC) 来减小纹理资源的大小,以及对运行时生成的纹理进行无损压缩。

占用率衡量当前整个线程池中有多少线程正在运行。 100% 的利用率意味着给定的 GPU 目前在线程数和可处理的总工作方面已达到最大值。

GPU 占用计数器测量 GPU 使用的总线程容量的百分比。 该总和是计算、顶点和片段占用率的总和。

隐 Surface 删除通常发生在片段处理之前每个渲染通道中间的某个位置 – 就在平铺顶点缓冲区发送到 GPU 进行光栅化之后。

深度缓冲和隐藏表面移除用于移除当前场景中视图相机不可见的任何表面。 这可以提高性能,因为不需要绘制这些曲面。

例如,不透明 3D 对象背面的表面不需要绘制,因为相机(和观看者)永远看不到它们 – 因此绘制它们没有意义。

相对于相机而言,被前面的其他 3D 对象遮挡的区域也会被删除。

删除隐藏表面时可以使用 GPU 计数器来增加光栅化的总数 Pixel,片段着色器的数量(实际上是调用片段着色器的数量)和存储的数量 Pixel 来确定。

GPU 计数器还可用于最大限度地减少混洗,这也会导致性能下降。

要通过移除遮挡表面来优化绘图,您应该按照对象的可见状态顺序绘制对象 – 即,测试对象是否不透明,测试半透明度,并尝试避免嵌套不透明和非不透明网格。

资源

要开始 Metal 优化,请务必查看 WWDC 视频使用 GPU 计数器优化 Metal 应用程序和游戏(来自 WWDC20)、利用 GPU 与 Metal(也来自 WWDC20)和部署优化的 Metal 应用程序 + 游戏(来自 WWDC19)。

接下来,继续阅读 Metal 调试器页面上的“在 Xcode 和 Metal 调试类型中捕获 Metal 工作负载” Apple的开发者文档网站。

Metal 调试器文档还包括分析 Metal 工作负载部分。

您绝对应该花大量时间阅读 Xcode 的 Metal Debugger 和 Trace 文档,以详细了解各种 GPU 计数器和性能图的工作原理。 如果没有这些,您将无法详细了解 Metal 代码中实际发生的情况。

对于压缩纹理,还值得了解自适应可扩展纹理压缩 (ASTC) 及其在现代渲染管道中的工作原理。

优化金属性能是一个庞大而复杂的主题——我们才刚刚开始,并将在以后的文章中进一步探讨这个主题。