Load resources faster with Metal 3
Graphics & Games 进阶 20m

使用 Metal 3 加速资源加载

Load resources faster with Metal 3

2022年6月6日

在 Apple 官方观看视频

一句话判断

Metal 3 的 Fast Resource Loading API 利用 Apple Silicon 统一内存架构和高速 SSD,让游戏可以异步、高吞吐、可优先级地流式加载纹理和几何数据——对大型游戏的加载体验优化至关重要。

这场 Session 讲了什么

GPU 软件工程师 Jaideep Joshi 介绍了 Metal 3 的 Fast Resource Loading 功能,这是一个专门为游戏和图形密集型 App 设计的异步资源加载 API。

核心思路:传统加载方式是同步的——App 必须等待存储操作完成才能继续编码渲染工作。Fast Resource Loading 通过 IO Command Queue 让加载操作异步执行,加载和渲染可以并行。同时支持并发执行多个 IO Command Buffer,充分利用高速 SSD 的吞吐能力。

三种加载命令:loadTexture(加载到 Metal 纹理)、loadBuffer(加载到 Metal 缓冲区)、loadBytes(加载到 CPU 可访问内存)。通过 Metal Shared Event 同步 IO 队列和渲染队列。

值得深挖的点

从”预加载一切”到”按需流式加载”的范式转变。 传统游戏在关卡开始时加载所有资源,玩家等进度条。Fast Resource Loading 支持以更小的粒度(如 sparse texture 的单个 tile)按需流式加载,玩家边玩边加载,加载屏幕可以大幅缩短甚至消除。

并发执行的 IO Command Buffer。 不仅同一个 IO Command Buffer 内的加载命令并发执行,不同 IO Command Buffer 之间也并发执行且可以乱序完成。这种设计最大化了存储硬件的吞吐利用率。

与渲染工作的同步机制。 IO Command Buffer 通过 signalEvent 在加载完成后通知渲染 Command Buffer,渲染 Command Buffer 通过 waitForEvent 等待。这种 event-based 同步比轮询或 CPU 阻塞高效得多。

代码片段

// 步骤 1:打开文件
let device = MTLCreateSystemDefaultDevice()!
let fileHandle = device.makeIOHandle(URL: fileURL)!

// 步骤 2:创建 IO Command Queue
let queueDesc = MTLIOCommandQueueDescriptor()
queueDesc.type = .concurrent  // 默认就是并发
let ioQueue = device.makeIOCommandQueue(descriptor: queueDesc)!

// 步骤 3:编码加载命令
let ioBuffer = ioQueue.makeCommandBuffer()!
ioBuffer.loadTexture(texture: texture,
                     slice: 0,
                     level: 0,
                     size: MTLSize(width: textureSize, height: textureSize, depth: 1),
                     sourceHandle: fileHandle,
                     sourceOffset: offset)

// 步骤 4:同步渲染工作
let sharedEvent = device.makeSharedEvent()!
ioBuffer.signalEvent(sharedEvent, value: 1)
ioBuffer.commit()

// 渲染 Command Buffer 等待加载完成
let renderBuffer = renderQueue.makeCommandBuffer()!
renderBuffer.waitForEvent(sharedEvent, value: 1)
// 现在可以安全使用已加载的纹理
renderBuffer.commit()

最佳实践

  • 使用更小的加载粒度。 Sparse texture 的 tile 级别加载比整个 mip level 加载灵活得多,减少不必要的数据传输。
  • 用优先级确保关键资源先就绪。 Fast Resource Loading 支持优先级设置,视口内可见的资源应该优先加载。
  • 避免过大的 threadgroup 尺寸。 使用最小的 SIMD width 倍数,让 GPU 更均匀地分配工作。
  • 用 Metal System Trace 和 GPU Debugger 分析加载性能。 检查 IO 队列的利用率和是否存在不必要的空闲时间。

还有什么值得关注

  • Fast Resource Loading 利用了 Apple Silicon 的统一内存架构,存储设备直接写入 GPU 可访问的内存
  • 支持从同一个文件的不同 offset 加载多个资源
  • IO Command Queue 可以配置为 sequential 模式,用于需要严格顺序的场景
  • 推荐搭配观看 Metal 3 的其他 Sessions 了解完整的图形管线更新
WWDC 2022