Запуск вычислительного ядра на часть MTLBuffer? - PullRequest
0 голосов
/ 15 июня 2019

Я заполняю MTLBuffer векторами float2.Буфер создается и заполняется следующим образом:

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]

В моем металлическом файле доступ к буферу осуществляется следующим образом:

struct Particle {
   float2 position;
   ...
};

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

Мне нужно иметь возможность вычислить заданный диапазонMTLBuffer.Например, возможно ли запустить вычислительное ядро, скажем, начиная со значения 50 000 и заканчивая значением 75 000?

Кажется, что параметр смещения позволяет мне указать начальную позицию, но у него нетПараметр длины.

Я вижу, что есть этот вызов:

setBuffers(_:offsets:range:)

Указывает ли диапазон, какую часть буфера запустить?Похоже, диапазон определяет используемые буферы, а не диапазон значений для использования.

1 Ответ

0 голосов
/ 16 июня 2019

Вычислительный шейдер не работает "на" буфере (или его части).Он работает на сетке, которая является абстрактной концепцией.Что касается Metal, то сетка не связана с буфером или чем-либо еще.

Буфер может быть входом, который использует ваш вычислительный шейдер, но как он его использует, зависит от вас.Металл не знает и не заботится.

Вот мой ответ на похожий вопрос .

Итак, команда отправки, которую вы кодируете с помощью кодера вычислительной команды, определяет, сколько разВаш шейдер вызывается.Он также определяет, какие значения thread_position_in_grid (и связанные с ними) получает каждый вызов. Если ваш шейдер соотносит каждую позицию сетки с элементом массива, поддерживаемым буфером, то количество потоков, которое вы указываете в своей команде dispatch, определяет, какой объем буфера вы получите в итоге.(Опять же, это не то, что диктует Metal; это неявно в том, как вы кодируете свой шейдер.)

Теперь, чтобы начать с 50 000-го элемента, используя смещение на привязке буфера, чтобы сделать это эффективным началомиз буфера с точки зрения шейдера это хороший подход.Но было бы также просто добавить 50000 к индексу, который вычисляет шейдер при обращении к буферу.А если вы хотите обработать только 25 000 элементов (75 000 минус 50 000), просто отправьте 25 000 потоков.

...