2016-11-18 9 views
2

2つの計算シェーダAとBをメタルにディスパッチするとします。私はAが完了するまでBを走らせたくありません。現時点では私は自分自身のコマンドバッファ内の各シェーダをコードしていますので、同様にコミット:次の計算シェーダで1つの計算シェーダの結果を使用する適切な方法

commandBufferA.commit() 
commandBufferA.waitUntilCompleted() 
commandBufferB.commit() 

が、これは適切なテクニックですか?

答えて

2

コマンドバッファにwaitUntilCompleted()を呼び出すことは、カーネルの結果をCPU上で使用する必要がある場合に便利ですが、単に計算コマンド(ディスパッチ)の結果を使用するだけでは不必要で非効率ですその後の計算コマンド。計算コマンド間にデータの依存関係がある場合、前者によって書かれた結果は、単一のコマンドバッファ内であっても、後者から見えることが保証される。したがって、次のような構造にすることができます:

let commandBuffer = commandQueue.makeCommandBuffer() 
let commandEncoder = commandBuffer.makeComputeCommandEncoder() 

commandEncoder.setComputePipelineState(pipelineStateA) 
commandEncoder.setTexture(inputTexture, at: 0) 
commandEncoder.setTexture(intermediateTexture, at: 1) 
commandEncoder.dispatchThreadgroups(threadgroupCount, 
            threadsPerThreadgroup: threadgroupSize) 

commandEncoder.setComputePipelineState(pipelineStateB) 
commandEncoder.setTexture(intermediateTexture, at: 0) 
commandEncoder.setTexture(outputTexture, at: 1) 
commandEncoder.dispatchThreadgroups(threadgroupCount, 
            threadsPerThreadgroup: threadgroupSize) 

commandEncoder.endEncoding() 
commandBuffer.commit() 

commandBuffer.waitUntilCompleted() // optional; only if you need to read the result on the CPU 
+0

これは、パフォーマンスを向上させるためにMBEのイメージフィルタリングの章に適用できますか?私が正しく覚えていれば、連鎖された各フィルターには独自のコマンドエンコーダーがありますか? –

+0

エンコーダ自体はかなり安いですが、参考にしているサンプルには、この質問で説明されている問題があります。つまり、ディスパッチごとにコマンドバッファを作成し、CPUが待機して結果を同期させることができます。私がそれを全面的にやっていたら、Metal Performance Shadersの見本とメリットの恩恵を受けて、私はそれを非同期にし、複数のフィルターで同じバッファーにエンコードされていることを確認します。生活し、学びます。 – warrenm

関連する問題