运行 在 MTLBuffer 的一部分上计算内核?

Running compute kernel on portion of MTLBuffer?

我正在用 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参数好像可以指定起始位置,但是没有length参数

我看到有这个电话:

setBuffers(_:offsets:range:)

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

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

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

这里是

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

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