【问题标题】:Threads and threadgroups in MetalMetal中的线程和线程组
【发布时间】:2019-05-26 02:21:02
【问题描述】:

我对每个线程组的线程数和线程组数有一些疑问。

  1. 既然我们有maxTotalThreadsPerThreadgroupthreadExecutionWidth,线程组的length * width * height 应该等于maxTotalThreadsPerThreadgroup。那么,如果我有maxTotalThreadsPerThreadgroup = 1024threadExecutionWidth = 32,如果我创建一个大小为(1024 * 1 * 1)32 * 32 * 1 的线程组有什么区别?总 GPU 执行时间有什么额外的好处吗?或者这只是为了更有效的管理?

  2. 如果我想运行的线程多于maxTotalThreadsPerThreadgroup,那么我将创建多个线程组。假设ThreadGroup1 将在ThreadGroup2 之前执行是否安全?

【问题讨论】:

    标签: macos gpu metal


    【解决方案1】:

    我不是 Metal 计算方面的权威人士,并且没有记录很多诸如此类的细节,因此请谨慎对待以下内容:

    1. 将线程组组织成 1、2 或 3 维对开发人员来说非常方便。如果您的问题是三维的,请使用具有 3 维的线程组。如果您的问题是一维的,请使用一维的线程组。金属并不真正关心一种或另一种方式。

    2. 我认为您无法假设线程组中 GPU 线程的调度顺序。

    例如,如果您安排 10 个线程组,每个线程组计算一个中间结果(例如总和),那么您可能不应该依赖第 10 个线程组来收集这些结果并将它们组合成一个最终结果(最终总和)。相反,您必须启动一个新的计算内核来执行此操作。

    (我很高兴被证明是错误的,但我还没有读到任何 Metal 保证这种事情的地方。)

    【讨论】:

    • 可能这就是为什么 Metal 没有任何用于排序和前缀和的预写内核的原因。由于线程组中的线程数量受到限制,并且无法确定首先执行哪个线程组,我认为如果不多次调用计算内核,就无法编写此类程序。
    • 但不是所有 GPGPU 语言都这样吗?
    • 我不确定。我看到了 CUDA 的排序和前缀总和 API,使用推力库。你是说推力还调用多个内核来对数据进行排序或计算前缀总和?
    • 前缀总和(或扫描)通常可以使用单个线程组完成。不确定如何在 CUDA 中实现排序。但是,是的,将一个操作分成多个阶段,每个阶段都有自己的计算内核,这是一种常见的方法。你不能在不同的线程组之间进行通信——我想依赖于它们执行的特定顺序是一种通信。
    • 创建你的命令缓冲区。对于您要运行的每个内核,为此命令缓冲区创建一个新的计算命令编码器,对内核进行编码。为所有内核完成此操作后,提交命令缓冲区。 GPU 现在将一个接一个地运行所有计算内核,但都在同一个工作中。
    猜你喜欢
    • 1970-01-01
    • 2015-02-28
    • 2018-06-07
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    相关资源
    最近更新 更多