【问题标题】:MPSImageGaussianBlur in a rendering pipeline渲染管道中的 MPSImageGaussianBlur
【发布时间】:2016-02-29 15:13:23
【问题描述】:

我有一个 MPSImageGaussianBlur 对象在计算通道的每一帧上工作(模糊中间纹理的内容)。

虽然应用程序仍然以 60fps 运行没问题,但我发现启用模糊通道后 CPU 使用率增加了约 15%。我想知道这是否正常?

我只是想知道MPSImageGaussianBlurencodeToCommandBuffer: 操作的后台会发生什么,它会看到如此多的 CPU 利用率。在我(虽然很天真)的理解中,我想会有一些简单的编码如下:

MPSImageGaussianBlur.encodeToCommandBuffer:伪方法:

func encodeToCommandBuffer(commandBuffer: MTLCommandBuffer, sourceTexture: MTLTexture, destinationTexture: MTLTexture) {

    let encoder = commandBuffer.computeCommandEncoder()
    encoder.setComputePipelineState(...)

    encoder.setTexture(sourceTexture, atIndex: 0)
    encoder.setTexture(destinationTexture, atIndex: 1)

    // kernel weights would be built at initialization and 
    // present here as a `kernelWeights` property
    encoder.setTexture(self.kernelWeights, atIndex: 2)

    let threadgroupsPerGrid = ...
    let threadsPerThreadgroup = ...
    encoder.dispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup)
    encoder.endEncoding()
}

大部分“性能魔法”将在计算内核函数中运行的算法上实现。我可以欣赏这一点,因为性能(在 GPU 上)非常棒,与我初始化 MPSImageGaussianBlur 的 blurRadius 无关。

一些可能与我的具体设置无关的细节:

  • MPSImageGaussianBlur 初始化为模糊半径 8 像素。
  • 我要模糊的纹理是 128 x 128 像素。
  • 在 MTKViewDelegate 的 drawInMTKView: 方法中执行所有渲染。

我希望这个问题的意图有点清楚。

【问题讨论】:

  • 为了确定,您只创建了一个MPSImageGaussianBlur 实例,并跨帧重复使用它,对吗?
  • 是的,只有一个实例
  • 您在哪个设备和 iOS 版本上看到此行为?
  • 我在装有 iOS 9.3 的 iPhone 6 上运行它。我正在使用 Xcode 7.3 beta 4 并跟踪仪器和调试导航器中的 CPU 使用情况。感谢您对此进行调查!
  • 更多细节:当您说~15% 时,您是说增加 15 个百分点,还是增加 15% 的 CPU 使用率?如果是后者,我会说这是意料之中的。如果是前者,这听起来像是一个相当大的倒退。您的典型模糊半径 (sigma) 是多少?

标签: metal


【解决方案1】:

MPSGaussianBlur 内部是一个复杂的多通道算法。它花费一些时间从其内部纹理缓存中分配纹理以保存中间数据。需要管理多个内核启动的开销。还需要设置一些资源,例如高斯模糊核权重。当您提交命令缓冲区时,所有这些纹理都需要连接(iOS)并且需要完成一些其他工作。所以,它并不像你想象的那么简单。

您使用的纹理足够小,相对固定的 CPU 开销可能会开始成为相当大的一部分时间。

对 MPSGassianBlur 的 CPU 成本进行调查会导致 Apple 花费一两个小时来查看是否可以改进,这值得您花时间。

【讨论】:

    【解决方案2】:

    老实说,如果 gpu 的访问量低于您对内核的想象,我不会感到惊讶。在我第一次使用金属计算时,我发现性能不佳,然后又回到了霓虹灯上。这是反直觉的。如果 CPU 命中是霓虹灯,我真的不会感到惊讶。我使用 mps Gaussian 也看到了同样的情况。很高兴得到证实。 Neon 有很多对这个用例更友好的内存和指令特性。

    此外,可能是这种情况的一个指标是这些过滤器不能在 OS X Metal 上运行。如果它只是计算着色器,我相信它们可以运行。但是 Neon 代码无法在模拟器上运行。

    【讨论】:

    • 没有 MPS 工作负载在 CPU 上运行。没有可用的方法来确保在金属命令缓冲区中 CPU 工作的正确时序。
    猜你喜欢
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    相关资源
    最近更新 更多