【问题标题】:Cuda How to run many threads from global function? One kernel which runs many threadsCuda 如何从全局函数运行多个线程?一个运行多个线程的内核
【发布时间】:2011-11-21 14:10:20
【问题描述】:

我需要让一部分计算并行。它是对向量的计算,有时我需要对每个值进行一次操作。所以我想让它平行。

我无法解释我对示例的计算(它只是简单的示例,不是我的算法): 我正在向前移动一个指针,当我找到数字 5 时,我将 5 添加到向量中的每个数字。

所以我想避免在主机上执行此操作,并在每个指针移动后将所有大向量复制到设备 主机(可重复)。我想它可能比在 Host 上做所有事情效率低。

所以我有了一个想法,我将所有向量复制到设备一次,然后我将开始算法。

这是一个简单的解决方案,可以解决我的问题:

__device__ void devFunction(long long unsigned int *arr, long long unsigned int param, long long unsigned int N) {
    long long unsigned int i = blockIdx.x* blockDim.x+ threadIdx.x;
    // do something ...
}

__global__ void globFunction(long long unsigned int *arr, long long unsigned int N) {

    do {
        devFunction(arr, param, N); // I want to run many threads here like <<<...>>>

        // do something ...

    } while(/* ... */);
}


int main() {
    // declare array, alloc memory, copy memory, etc.
    globFunction<<< 400000, 256>>>(arr, N); // I think here should be <<<1,1>>>
    // do something ...
    return 0;
}

那么有可能吗?从内核并行运行多个函数?还有其他解决方案吗?

【问题讨论】:

  • 为什么需要从单个 cuda 线程生成更多线程?您不能只在主机的多个线程上调用内核并并行运行计算吗?
  • 它可能会更慢,因为每个线程都会做同样的思考 -> 将指针通过这个大向量向前移动并将它(在示例情况下)与数字 5 进行比较。我只需要在一个线程中执行它并且只有一次。只有每个线程上的其他计算。
  • @nosbor:所以您想知道是否可以并行“做某事”?这不是一个非常精确的问题,是吗?

标签: c++ c parallel-processing cuda


【解决方案1】:

不,这是不可能的。但是您可能会以错误的方式处理此问题:只有主内核函数才需要计算线程索引,并且您应该以每个线程都有独立工作要做的方式设计代码.这就是可并行化问题的本质。并行代码中不应存在分支或跨线程数据依赖。

作为一个粗略的骨架示例,代码应如下所示:

__global__ void kernel(int * indata, int * outdata)
{
  unsigned int tid = threadId.x + blockDim.x * blockId.x; // or suitable analogue

  device_computation(indata + tid, outdata + tid);
}

__device__ void device computation(int * in, int * out)
{
  // This code does not care about the thead ID
  // -- it is already local to one single thread
  *out = *in * 2;
}

您真的不应该任何需要知道indata[j] 来计算indata[i]。如果这样做,则必须对数据进行分区,以便执行计算所需的所有数据仅对单个线程可见。

如果不能这样设计代码,则会严重影响性能,您应该调查它是否真的值得并行化。

(这个例子过于简单了;当然应该考虑到使用块共享内存的机会。但是,这并不影响每个线程应该能够独立于其他线程运行的事实。)

【讨论】:

  • 是的,但是当您考虑示例问题时,不可能使它看起来像这样。
  • @nosbor:我真的看不出你的代码在做什么,但你应该尝试将它分成可以独立完成的部分,或者以最少的同步。
猜你喜欢
  • 1970-01-01
  • 2010-12-06
  • 2016-05-08
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-17
相关资源
最近更新 更多