【问题标题】:CUDA how to trick the kernel into thinking it's in another thread?CUDA如何欺骗内核认为它在另一个线程中?
【发布时间】:2015-02-06 23:55:18
【问题描述】:

我正在为 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* 的最佳方法是什么?

【问题讨论】:

  • 也许只有我一个人,但我发现几乎不可能理解你想要达到的目标。你能说出你的确切目标、预期结果和观察到的结果吗?
  • 将索引计算移动到全局函数中,并将索引和dim传递给设备函数。您要么需要全局函数具有固定的分区方案,要么使用原子请求下一个工作块。
  • 我正在尝试做一个 API,以便用户可以运行任意数量的线程并且 API 将处理这些作业。
  • @Jean-LucNacifCoelho 你打算如何支持__syncthreads()

标签: c++ c multithreading cuda


【解决方案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-th部分数据。对于多个维度,您还可以更改签名void (*func)(int i, int j, int k, void*)。我认为这应该更可取,因为 __device__ 函数也可以声明为 __host__ 并且您可以在 CPU 中并行运行它。

对于void* 问题,我可以推荐在 C++ 中使用模板(+可变参数模板),但在 C 中没关系。

【讨论】:

  • 我不是要写func的人。我希望它表现得像 pthreads 和 func 是一个普通的 cuda 内核。
  • @Jean-LucNacifCoelho 对于这样的 API,最终用户将不得不处理诸如 __shared__ 内存使用或 __syncthreads 之类的限制。即使在 pthreads 中,如果你想要比运行数据独立函数更复杂的东西,你也必须处理线程管理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
相关资源
最近更新 更多