繁体   English   中英

金属功能多次调用的性能

[英]Performance of metal function multiple call

我使用Apple Metal对iPhone / iPad进行了刚体仿真。 为此,我需要多次调用内核函数,并且我看到这需要很长时间,例如与CUDA相反。 我实现了Metal内核函数调用,如Apple教程中所述

let commandQueue = device.newCommandQueue()

var commandBuffers:[MTLCommandBuffer]=[]
var gpuPrograms:[MTLFunction]=[]
var computePipelineFilters:[MTLComputePipelineState]=[]
var computeCommandEncoders:[MTLComputeCommandEncoder]=[]

//here i fill all arrays for my command queue
//and next i execute it 

let threadsPerGroup = MTLSize(width:1,height:1,depth:1)
let numThreadgroups = MTLSize(width:threadsAmount, height:1, depth:1)

for computeCommandEncoder in computeCommandEncoders
{
    computeCommandEncoder.dispatchThreadgroups(numThreadgroups, threadsPerThreadgroup: threadsPerGroup)
}

for computeCommandEncoder in computeCommandEncoders
{
    computeCommandEncoder.endEncoding()
}

for commandBuffer in commandBuffers
{
    commandBuffer.enqueue()
}

for commandBuffer in commandBuffers
{
    commandBuffer.commit()
}

for commandBuffer in commandBuffers
{
    commandBuffer.waitUntilCompleted()
}

我每帧最多要处理几十个金属内核函数,而且它的工作速度太慢。 我用空的内核函数进行了测试-它向我展示了问题出在执行的Swift部分。 我的意思是,当我想在CUDA中执行内核函数时,我就像平常的函数一样调用它,并且它的运行速度非常快。 但是在这里,我必须为每个框架的每个函数的每次执行执行许多操作。 可能是我一无所知,但是我想一次创建所有其他对象,然后像

 commandQueue.execute()

执行所有内核功能。

我是否有权执行许多内核功能,或者还有其他方法可以更快地执行它?

我有几个项目在单个步骤中使用多个着色器。 我只创建一个缓冲区和编码器,但创建多个管道状态。 每个计算功能一个。

请记住, MTLCommandQueue是持久性的,因此只需要创建一次,因此我的MetalKit View的drawRect()函数大致是这样(它们之间传递了更多的着色器和纹理,但您对结构有所了解):

let commandBuffer = commandQueue.commandBuffer()
let commandEncoder = commandBuffer.computeCommandEncoder()

commandEncoder.setComputePipelineState(advect_pipelineState)
commandEncoder.dispatchThreadgroups(threadgroupsPerGrid, 
    threadsPerThreadgroup: threadsPerThreadgroup)

commandEncoder.setComputePipelineState(divergence_pipelineState)
commandEncoder.dispatchThreadgroups(threadgroupsPerGrid, 
    threadsPerThreadgroup: threadsPerThreadgroup)

[...]

commandEncoder.endEncoding()
commandBuffer.commit()

我的代码实际上在20个着色器上进行了20次迭代,并且仍然运行得很顺畅,因此,如果您重组并遵循具有单个缓冲区和单个编码器的结构,并且每次通过仅调用endEncoding()commit()一次,则可能看到性能的提高。

可能是有效的词:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM