Как Metal распределяет блок изображения по каждой группе нитей? - PullRequest
2 голосов
/ 20 апреля 2019

enter image description here enter image description here

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

NSUInteger maxTotalThreadsPerThreadgroup = [self.computePipelineState maxTotalThreadsPerThreadgroup];
MTLSize threadgroupCounts = MTLSizeMake(threadExecutionWidth * 2, threadExecutionWidth * 2, 1);
MTLSize threadsPerThreadGroup = MTLSizeMake([self.texutre width] / threadgroupCounts.width + 1,
[self.texutre height] / threadgroupCounts.height + 1,
1);

Я знаю, что изображение будет разделено на разные блоки, и каждый из них будет обрабатываться одной группой потоков. Но, похоже, в ядре мы просто прочитаем 2d текстуру, а затем выведем обработанную текстуру.

Но вопрос в том, как изображение нарезается на разные 2d текстуры? Как мы узнаем, что каждый блок изображения назначен потоку для обработки? Это сделано самим Металлом? Или нам нужно вручную назначить каждый блок каждой группе потоков, используя gid ?

1 Ответ

4 голосов
/ 20 апреля 2019

Металл не знает и не заботится, работает ли ваш шейдер на изображении. Это не «рубит» изображение или что-то в этом роде.

Вычислительный шейдер обрабатывается по «сетке». Сетка - это абстракция. Это произвольный способ организовать работу. Металл не придает сетке никакого значения, например, связывает позицию в сетке с пикселем на изображении.

Такая связь, если она существует, подразумевается в поведении вашего шейдерного кода. Да, это во многом зависит от того, что делает шейдер с thread_position_in_grid, thread_position_in_threadgroup, thread_index_in_threadgroup и т. Д.

Итак, если вы используете переменную gid с атрибутом thread_position_in_grid и используете ее координаты в качестве координат изображения, то именно это использование определяет, что каждая позиция сетки соответствует пикселю изображения. Как только вы это сделаете, из этого следует, что каждая группа потоков соответствует блоку изображения, поскольку группа потоков - это просто блок позиций сетки. Но опять же, это не то, что делает Metal, это то, что делает ваш шейдер.

Вы могли бы сделать что-то совершенно другое, и Металлу было бы все равно.

...