【问题标题】:How Metal distribute the image block to each thread group?Metal如何将图像块分配给每个线程组?
【发布时间】:2019-04-19 21:39:53
【问题描述】:

例如,如果我要进行灰度转换,我需要通过以下方式设置我的threadsPerGroup和线程组。

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 纹理?我们如何知道每个图像块是否被分配给一个线程来处理?这是由 Metal 自己完成的吗?或者我们需要使用 gid 手动将每个块分配给每个线程组?

【问题讨论】:

    标签: metal


    【解决方案1】:

    Metal 不知道也不关心您的着色器是否在图像上运行。它不会“切割”图像或类似的东西。

    计算着色器在“网格”上进行处理。网格是一种抽象。这是您组织工作的任意方式。 Metal 不会为网格分配任何意义,例如将网格中的位置与图像中的像素相关联。

    这种关联(如果存在)隐含在着色器代码的行为方式中。是的,这主要基于着色器对thread_position_in_grid、thread_position_in_threadgroup、thread_index_in_threadgroup 等所做的操作。

    因此,如果您使用带有thread_position_in_grid 属性的gid 变量,并且将其坐标用作图像坐标,那么这种用法决定了每个网格位置对应于图像像素。一旦你这样做了,那么每个线程组都对应于图像的一个块,因为一个线程组只是一个网格位置块。不过,这又不是 Metal 正在做的事情,而是您的着色器正在做的事情。

    你可以做一些完全不同的事情,Metal 不会在意。

    【讨论】:

      猜你喜欢
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      • 2012-06-07
      • 1970-01-01
      • 2021-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多