渲染管道

时间:2016-02-29 15:13:24

标签: metal

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

虽然应用程序仍然以60fps的速度运行没问题,但是在启用模糊传递时,我看到CPU使用率增加了约15%。我想知道这是否正常?

我只是好奇在MPSImageGaussianBlur encodeToCommandBuffer:操作的引擎下会发生什么样的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上)非常出色,与blurRadius无关我使用MPSImageGaussianBlur初始化。

有关我的具体设置的一些可能不相关的细节:

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

我希望这个问题在其意图中有些明确。

2 个答案:

答案 0 :(得分:1)

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

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

向MPSGassianBlur的CPU成本提供雷达将导致Apple花一两个小时来查看是否可以改进某些内容,并且值得花时间。

答案 1 :(得分:-1)

老实说,如果在引擎盖下gpu的访问量低于你对内核的想法,我不会感到惊讶。在我第一次使用金属计算机的经历中,我发现性能不佳,并再次落后于霓虹灯。这是违反直觉的。如果cpu命中是霓虹灯,我真的不会感到惊讶。我用mps高斯看到了同样的东西。得到这个证实会很高兴。 Neon有很多内存和指令功能,对这个用例更友好。

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