嘿 我有两个大小为2000的数组。我想写一个内核将一个数组复制到另一个数组。该阵列代表1000个粒子。 index 0-999将包含一个x值,1000-1999为其位置的y值。
我需要一个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>>>(...);
答案 0 :(得分:3)
这会有效吗?
你真的尝试过吗?
它将无法启动,因为您最多可以拥有512个线程(不同架构的值可能会有所不同,我的是GTX 200系列之一)。您将需要更多的块或更少的线程以及内部的for循环blockDim.x
增量。
您的多块解决方案也应该有效。
其他方法
如果这是内核的唯一目的,您也可以尝试使用cudaMemcpy
作为最后一个参数{/ 1}}。
答案 1 :(得分: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可能是一个定义或命令行参数,或者迭代来测试许多配置)
答案 2 :(得分:0)
最好为任何内核使用多个块。
在我看来,您只是将一个数组从一个数组复制到另一个数组,作为带有偏移量的值序列。 如果是这种情况,您只需使用 cudaMemcpy API调用并指定即可 的 cudaMemcpyDeviceToDevice 强>
cudaMemcpy(array1+halfway,array1,1000,cudaMemcpyDeviceToDevice);
API将找出块/线程的最佳分区。