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

时间:2015-02-06 23:55:18

标签: c++ c multithreading cuda

我正在为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 *?

1 个答案:

答案 0 :(得分:1)

嗯,我认为一般来说实现目标有点困难。 但是根据您的问题,我可以得出结论,您的函数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中没问题。