2016-02-29 37 views
1

我有一个MPSImageGaussianBlur对象在计算传递的每一帧上进行工作(模糊中间纹理的内容)。渲染管道中的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上)非常棒,独立于blurRadius,我初始化了MPSImageGaussianBlur

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

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

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

+0

可以肯定的是,您只是创建了一个'MPSImageGaussianBlur'实例,然后跨帧复用它,是否正确? – warrenm

+0

是的,只是一个实例 – jameslintaylor

+0

哪个设备和iOS版本是你看到的这种行为? – warrenm

回答

-1

我真的不会感到惊讶,如果在引擎盖下gpu被访问的次数少于你对内核的想象。在我对金属计算机的第一次经历中,我发现性能不俗,并在霓虹灯上再次回落。这是违反直觉的。如果cpu命中霓虹灯,我真的不会感到惊讶。我看到使用mps高斯相同。这将很高兴得到证实。霓虹有很多内存和指令功能,对这个用例更友好。

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

+0

没有MPS工作负载在CPU上运行。没有可用的方法来确保CPU在金属命令缓冲区中工作的正确时间。 –

0

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

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

对MPSGassianBlur的CPU成本计算雷达会导致Apple花费一两个小时的时间寻找是否可以改进的东西,并且将会值得你花时间。