我有一个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像素。drawInMTKView:
方法中执行所有渲染。我希望这个问题在其意图中有些明确。
答案 0 :(得分:1)
MPSGaussianBlur内部是一个复杂的多通道算法。它花费一些时间从其内部纹理缓存中分配纹理来保存中间数据。需要管理多个内核启动的开销。还需要设置一些资源,如高斯模糊核权重。提交命令缓冲区时,所有这些纹理都需要连接(iOS),还需要完成其他一些工作。所以,它并不像你想象的那么简单。
您使用的纹理足够小,相对固定的CPU开销可能会开始成为可观的部分时间。
向MPSGassianBlur的CPU成本提供雷达将导致Apple花一两个小时来查看是否可以改进某些内容,并且值得花时间。
答案 1 :(得分:-1)
老实说,如果在引擎盖下gpu的访问量低于你对内核的想法,我不会感到惊讶。在我第一次使用金属计算机的经历中,我发现性能不佳,并再次落后于霓虹灯。这是违反直觉的。如果cpu命中是霓虹灯,我真的不会感到惊讶。我用mps高斯看到了同样的东西。得到这个证实会很高兴。 Neon有很多内存和指令功能,对这个用例更友好。
此外,可能出现这种情况的指标是这些过滤器不能在OS X Metal上运行。如果它只是计算着色器,我相信它们可以运行。但是Neon代码无法在模拟器上运行。