我需要让计算的一部分是并行的。它是向量计算,有时我需要对每个值进行一次运算。所以我想让它成为平行。
我无法解释我在示例上的计算(它唯一的简单示例,而不是我的算法): 我向前移动一个指针,当我找到数字5时,我在向量中的每个数字加上5。
所以我想避免在Host上进行,并将所有Big vector复制到Device< =>每个指针移动后主机(可重复)。我认为它可能比在Host上的所有内容效率低。
所以我知道我会将所有向量复制到Device一次然后我将启动算法。
这是一个简单的应对方案,提出了我的问题:
__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 :(得分: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]
。如果这样做,那么您必须对数据进行分区,以便执行计算所需的所有数据仅对单个线程可见。
如果代码不能以这种方式设计,它将遭受严重的性能命中,你应该调查它是否真的值得并行化。
(这个例子过于简单;当然应该考虑使用块共享内存的机会。但是,这并不影响每个线程应该能够独立于其他线程运行的事实。)