2016-02-29 181 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花費一兩個小時的時間尋找是否可以改進的東西,並且將會值得你花時間。