Metal如何将图像块分配给每个线程组?
Posted
技术标签:
【中文标题】Metal如何将图像块分配给每个线程组?【英文标题】:How Metal distribute the image block to each thread group? 【发布时间】: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 手动将每个块分配给每个线程组?
【问题讨论】:
【参考方案1】:Metal 不知道也不关心您的着色器是否在图像上运行。它不会“切割”图像或类似的东西。
计算着色器在“网格”上进行处理。网格是一种抽象。这是您组织工作的任意方式。 Metal 不会为网格分配任何意义,例如将网格中的位置与图像中的像素相关联。
这种关联(如果存在)隐含在着色器代码的行为方式中。是的,这主要基于着色器对thread_position_in_grid
、thread_position_in_threadgroup
、thread_index_in_threadgroup
等所做的操作。
因此,如果您使用带有thread_position_in_grid
属性的gid
变量,并且将其坐标用作图像坐标,那么这种用法决定了每个网格位置对应于图像像素。一旦你这样做了,那么每个线程组都对应于图像的一个块,因为一个线程组只是一个网格位置块。不过,这又不是 Metal 正在做的事情,而是您的着色器正在做的事情。
你可以做一些完全不同的事情,Metal 不会在意。
【讨论】:
以上是关于Metal如何将图像块分配给每个线程组?的主要内容,如果未能解决你的问题,请参考以下文章