【问题标题】:GPU Kernel Blocksize/Gridsize without Threads无线程的 GPU 内核块大小/网格大小
【发布时间】:2023-04-11 06:13:02
【问题描述】:

我目前正在通过 pycuda/cuda 在 gpu 上编写一些数值方法,并且正在编写自己的内核。在某些时候,我需要估计至少 1000 个耦合 ODE 的误差。我不想复制两个超过 1000 个条目的向量,所以我创建了一个内核(在帖子的底部),它是一个基本的 max 函数。这些 %(T)s 和 %(N)s 是我在运行时进行的字符串替换,这应该与这个问题无关(T 代表复杂数据类型,N 代表耦合 ODE 的数量)。

我的问题是:不需要并行计算,所以我不使用线程。当我在python中调用这个函数时,我应该指定blocksize还是gridsize?

        __global__ void get_error(double *max_error,%(T)s error_vec[1][%(N)s])
    {
        max_error[0]=error_vec[0][0].real();
        for(int ii=0;ii<%(N)s;ii=ii+1)
        {
            if(max_error[0] < error_vec[0][ii].real())
            {
                max_error[0]=error_vec[0][ii].real();
            }
        }
        return;
    }

【问题讨论】:

  • blocksize 为 1 和 gridsize 为 1 将使您在 GPU 上获得一个执行线程
  • @RobertCrovella 谢谢,即使我没有链接到 threadId 的任何变量,gpu 也会使用一个线程来执行?
  • 正确。相信您作为 C/C++ 程序员的知识(无论它是什么)。
  • 太好了,谢谢@RobertCrovella!

标签: python cuda gpu


【解决方案1】:

在内核启动中,将在 GPU 上启动的线程总数等于为启动指定的网格大小和块大小的乘积。

这两个值都必须是正整数,因此唯一可能的组合是 1,1 以创建单个线程的启动。

CUDA 内核不需要对内置变量(例如blockIdxthreadIdx 等)进行任何特定引用,但通常这样做是为了区分线程之间的行为。如果您只启动一个线程,则没有特别的理由使用这些变量,也没有必要这样做。

仅启动单个线程的 CUDA 内核并不是完成工作的高效方法,但在某些特定情况下这样做很方便,并且对整个应用程序的性能没有显着影响。

对我来说,为什么您提出的内核不能重铸为线程并行内核(它似乎正在执行max-finding reduction)对我来说并不明显,但这似乎与您的问题无关。

【讨论】:

  • 你怎么能找到并行的最大值?
  • 基本算法称为并行归约,是well-documented。出于说明的目的,大多数处理假设归约操作是所有元素的总和,但是找到所有元素的最大值(或所有元素的最小值)的过程只是微不足道的不同。 Here 是一个 cuda 标记问​​题,讨论最大发现减少。
猜你喜欢
  • 2014-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2019-07-09
  • 2013-06-06
  • 2014-01-19
  • 2018-04-18
相关资源
最近更新 更多