2011-11-21 58 views
0

我需要使计算的一部分是并行的。它是关于矢量的计算,有时我需要对每个值进行一次操作。所以我想让它平行。Cuda如何从全局函数运行多个线程?一个运行多线程的内核

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

所以我想避免这样做对主机和复制所有大载体,设备的每一个指针移动后< =>主机(repetable)。我想它可能比主机上的所有东西都低效。

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

下面是一个简单的应对提出我的问题:

__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; 
} 

所以这是可以做到的呢?从内核并行运行多个函数?其他解决方案?

+0

为什么你需要从一个cuda线程产生更多的线程?难道你不能在主机的许多线程上调用内核并且同时运行计算吗? – Tudor

+0

它可能会比较慢,因为每个线程都会执行相同的思考 - >通过这个Big vector向前移动指针并将其与数字5进行比较(在示例中)。我只需要在一个线程中执行一次并且只执行一次。只有每个线程上的其他计算。 – nosbor

+0

@nosbor:所以你想知道是否有可能“平行做事”?这不是一个非常确切的问题,是吗? – talonmies

回答

5

不,那是不可能的。但是,你可能要对这个错误的方式:只有主内核函数应该有必要计算线程索引,你应该以这样的方式,每个线程拥有独立工作做设计的代码。这是可并行化问题的本质。并行代码中不应该存在分支或跨线程数据依赖性。

的粗骨架例如,代码应该是这个样子:

__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]。如果你这样做,那么你就必须重新分区的数据,使得该对执行计算所需的所有数据可见专门为一个单独的线程。

如果代码不能这样设计的,它会受到严重的性能命中,你应该调查是否实际上是值得并行化。

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

+0

是的,但是当您考虑示例问题时,无法使其看起来像这样。 – nosbor

+0

@nosbor:我看不出你的代码在做什么,但你应该尝试将它分成可以独立完成的部分,或者用最少的同步。 –