【问题标题】:Running compute kernel on portion of MTLBuffer?在 MTLBuffer 的一部分上运行计算内核?
【发布时间】:2019-10-30 00:46:29
【问题描述】:

我正在使用 float2 向量填充 MTLBuffer。缓冲区的创建和填充如下:

struct Particle {
   var position: float2
   ...
}

let particleCount = 100000
let bufferSize = MemoryLayout<Particle>.stride * particleCount
particleBuffer = device.makeBuffer(length: bufferSize)!

var pointer = particleBuffer.contents().bindMemory(to: Particle.self, capacity: particleCount)
pointer = pointer.advanced(by: currentParticles)
pointer.pointee.position = [x, y]

在我的 Metal 文件中,缓冲区的访问方式如下:

struct Particle {
   float2 position;
   ...
};

kernel void compute(device Particle *particles [[buffer(0)]], 
                    uint id [[thread_position_in_grid]] … ) 

我需要能够计算给定范围的 MTLBuffer。例如,是否可以从 50,000 值开始到 75,000 值结束运行计算内核?

好像 offset 参数可以让我指定起始位置,但它没有长度参数。

我看到有这个电话:

setBuffers(_:offsets:range:)

范围是否指定要运行缓冲区的哪个部分?似乎范围指定了使用的缓冲区,而不是要使用的值的范围。

【问题讨论】:

    标签: ios swift buffer metal


    【解决方案1】:

    计算着色器不会“在”缓冲区(或部分)上运行。它在网格上运行,这是一个抽象概念。就 Metal 而言,网格与缓冲区或其他任何东西无关。

    缓冲区可能是您的计算着色器使用的输入,但如何使用它取决于您。金属不知道也不关心。

    这里是my answer to a similar question

    因此,您使用计算命令编码器编码的调度命令控制着调用着色器的次数。它还规定了每次调用接收的thread_position_in_grid(和相关)值。 如果您的着色器将每个网格位置与由缓冲区支持的数组的元素相关联,那么您在调度命令中指定的线程数将决定您最终访问多少缓冲区。 (同样,这不是 Metal 规定的;它隐含在您编写着色器的方式中。)

    现在,从第 50,000 个元素开始,使用缓冲区绑定上的偏移量来确保从着色器的角度来看缓冲区的有效开始是一个好方法。但它也可以在着色器访问缓冲区时将 50,000 添加到着色器计算的索引中。而且,如果您只想处理 25,000 个元素(75,000 减去 50,000),那么只需调度 25,000 个线程。

    【讨论】:

    • 谢谢肯。在意识到关键是线程之后,我只是来更新我的问题,但你打败了我。再次感谢!
    猜你喜欢
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    相关资源
    最近更新 更多