我有一个循环,将作业发送到托管内存模型中的 GPU。代码是:
var commandBufferArray : [MTLCommandBuffer] = []
var blitCommandArray : [MTLBlitCommandEncoder] = []
for i_cycle in 0..<n
{
commandBufferArray.append(mc.metalCommandQueue.makeCommandBuffer())
let outputDeviate = [float4](repeating: float4(0.0),count: 1024)
outputDeviateBufferArray.append(mc.createFloat4MetalBufferManaged(outputDeviate))
populateBuffersMetalJob(.....)
blitCommandArray.append(commandBufferArray[i_cycle].makeBlitCommandEncoder())
blitCommandArray[i_cycle].synchronize(resource: outputDeviateBufferArray[i_cycle])
blitCommandArray[i_cycle].endEncoding()
commandBufferArray[i_cycle].addCompletedHandler({ _ in
// do stuff with result
})
commandBufferArray[i_cycle].commit()
}
for i_cycle in 0..<numCycles
{
commandBufferArray[i_cycle].waitUntilCompleted()
}
我在 2015 MBP 上使用 AMD 工艺。如果 n = 1,则效果很好。一旦 n > 1,它似乎会挂起同步调用并且永远不会完成。
对这里出了什么问题有什么想法吗?
最佳答案
//do stuff with result
代码中有什么内容?我怀疑你正在做一些陷入僵局的事情。也许它正在尝试在主线程上运行某些内容,而您所显示的代码被阻止。或者它正在尝试访问您已锁定的资源。这会阻止已完成的处理程序完成,从而阻止命令缓冲区继续运行并让下一个命令缓冲区运行或完成。
如果您对流程进行采样,它可以提供有关卡在何处以及正在等待什么的提示。您可以使用sample
命令行工具或“事件监视器”>“ View ”>“示例进程”来执行此操作。
另外,为什么要使用多个命令缓冲区?为什么使用多个 blit 命令编码器?您确实意识到可以使用单个命令缓冲区和单个 blit 命令编码器来完成所有这些操作,对吗?
关于metal - 多线程情况下的 Apple Metal blitCommandEncoder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45000899/