2011-03-15 32 views
0

嘿, 我有两个2000的数组。我想编写一个内核将一个数组复制到另一个数组。该阵列代表1000个粒子。索引0-999将包含一个x值和1000-1999位置的y值。CUDA - 指定<<<x,y> >> for for循环

我需要一个for循环来复制从1个数组到另一个数组的N粒子。例如:

int halfway = 1000; 
    for(int i = 0; i < N; i++){ 
     array1[i] = array2[i]; 
     array1[halfway + i] = array[halfway + i]; 
    } 

由于N的数量始终小于2000,我可以创建2000个线程吗?或者我必须创建几个块。

我在想这样一个内核中:

int tid = threadIdx.x; 

    if (tid >= N) return; 

    array1[tid] = array2[tid]; 
    array1[halfway + tid] = array2[halfway + tid]; 

,并调用它,如下所示:

kernel<<<1,2000>>>(...); 

将这项工作?它会很快吗?或者我会更好地将问题分解成块。我不知道如何做到这一点,也许(这是正确的?)

int tid = blockDim.x*blockIdx.x + threadIdx.x; 

    if (tid >= N) return; 

    array1[tid] = array2[tid]; 
    array1[halfway + tid] = array2[halfway + tid]; 

    kernel<<<4,256>>>(...); 

回答

3

将这项工作?

你真的试过了吗?

它将无法启动,因为您最多可以有512个线程(值可能因体系结构不同而不同,我的是GTX 200系列之一)。您将需要更多的块或更少的线程和内部的for循环,增量为blockDim.x

您的多块解决方案应该也能正常工作。

其他方法

如果这是内核的唯一目的,你不妨试试使用cudaMemcpycudaMemcpyDeviceToDevice作为最后一个参数。

+0

我正在尝试的东西出来,它只是需要接近10分钟我的程序运行。当然,我认为'cudaMemcpy'就够了。你是说我的多块解决方案可以像现在这样工作,或者我需要一个带有'blockDim.x'增量的for循环? 4是块数的明智选择?干杯 – user660414 2011-03-15 16:29:09

+1

我还补充说,由于在主机和设备之间移动数据的速度有多慢,因此需要大量的计算才能使GPU的性价比更高。在这种情况下,如果内核比CPU上的简单for循环更快,我会感到惊讶。 如果你正在用这些设备内存粒子阵列进行其他计算,我希望是这种情况,那么值得的是什么:) – tugudum 2011-03-15 16:31:10

+0

@ user660414您需要循环以支持大于4 * 256的数组。 – tugudum 2011-03-15 16:35:23

0

回答有关配置问题的唯一方法是测试它们。要做到这一点,编写你的内核,以便它们工作,不管配置如何。通常,我会假设我将启动足够的线程,这使得内核更容易编写。然后,我会做这样的事情:

threads_per_block = 512; 

num_blocks = SIZE_ARRAY/threads_per_block; 
if(num_blocks*threads_per_block<SIZE_ARRAY) 
    num_blocks++; 

my_kernel <<< num_blocks, threads_per_block >>> (...); 

(除,当然,threads_per_block可能是一个定义,或命令行参数,或迭代测试许多配置)

0

是更好地使用更多对于任何内核来说都不止一块。

它似乎对我来说,你是简单地从一个数组复制到另一个作为一个值的序列与偏移量。 如果是这样,你可以简单地使用cudaMemcpy API调用,并指定 cudaMemcpyDeviceToDevice

cudaMemcpy(array1+halfway,array1,1000,cudaMemcpyDeviceToDevice); 

的API会找出块/线程的最佳分区的情况。

+0

由于设备的调度机制。每个GPU有多个SM,每个块只能在一个SM上运行。如果您有多个模块,则每个模块都可以运行在不同的SM上,充分利用其硬件 – fabrizioM 2011-03-16 20:57:06

相关问题