CUDA 如何欺骗内核认为它在另一个线程中?

CUDA how to trick the kernel into thinking it's in another thread?

本文关键字:另一个 线程 内核 何欺骗 欺骗 CUDA      更新时间:2023-10-16

我正在为 CUDA 内核函数编写一个包装器来管理线程分配,以隐藏 GPU 中的线程限制。发生的情况是,由于 CUDA 有线程限制,用户必须编写一个程序来管理线程。我试图做的是对用户隐藏线程限制,以便他可以在任意数量的线程中运行他的内核。

基本思想是这样的:

void launch_cuda_kernel_matrix(void (*func)(void*), void* param, unsigned int dim_x, unsigned int dim_y) {
    while (! all threads run) {
        do stuff ...
        fake_func<<max_x, max_y>>(func, param, current_run);
    }
}
void fake_func(void (*func)(void*), void* param, unsigned int current_run) {
    blockIdx.x = blockIdx.x (some math) current_run;
    threadIdx.x = threadIdx.x (some math) current run;
    func(param);
}

所以基本上我的计划是通过更改当前线程的线程和块索引来欺骗内核,然后使用最大可用线程数从我的包装器调用函数(我最终将推广我的架构以允许多个维度(

问题是,CUDA 不允许我更改线程和块索引。有没有办法解决这个问题?

另外,将参数传递给 func 而不必诉诸 void* 的最佳方法是什么?

嗯,我认为一般来说很难

实现你的目标。但是,从您的问题中我可以得出结论,您的函数func线程之间没有数据依赖关系(每个线程处理自己的部分,并且与其他线程没有交互(。还假设func处理 1 个维度(或 2 个维度(。由于这在 CUDA 中,您可以简单地运行大量线程,在大多数情况下就足够了:

  • 计算能力 1.x - 65535 x 1024 线程
  • 计算能力 2.0+ - 65535 x 65535 x 65535 x 1024 线程

另一种方法是将func签名更改为 void (*func)(int i, void*) ,因此该函数将处理i部分数据。对于多个维度,您还可以更改签名void (*func)(int i, int j, int k, void*)。在我看来,这应该是可取的,因为__device__函数也可以声明为 __host__,您可以在 CPU 中并行运行它。

void*问题,我可以建议在C++(+可变参数模板(中使用模板,但在 C 中没关系。