2013-02-08 94 views
0

我试着搜索类似的问题,但找不到一个,虽然有一对夫妇有一个类似的标题。CUDA在相同的参数上多次调用内核函数

我对主机像这样的代码:

handle_error(cudaMalloc((void**)&ret_dev, FLOAT_SIZE*no_kstrings*M)); 
for(int div=0;div<no_kstrings/threads;div++){ 
    kernel<<<grid_dim,block_dim>>>(ret_dev, v_freq_vectors, &no_kstrings[threads]); 
    handle_error(cudaMemcpy(&exp_freq[threads], ret_dev, FLOAT_SIZE*threads*M, 
     cudaMemcpyDeviceToHost)); 
} 

基本上我有运行在循环中的代码为最大无的倍数。每块的线程数。内核函数只是做一些事情,并将数据放入ret_dev。所以我想知道,在每次迭代之后我需要做cudaMemcpy()还是我可以在循环之外做到这一点?事情是这样的:

handle_error(cudaMalloc((void**)&ret_dev, FLOAT_SIZE*no_kstrings*M)); 
for(int div=0;div<no_kstrings/threads;div++){ 
    kernel<<<grid_dim,block_dim>>>(ret_dev, v_freq_vectors, &no_kstrings[threads]); 
} 
handle_error(cudaMemcpy(exp_freq, ret_dev, FLOAT_SIZE*no_kstrings*M, 
    cudaMemcpyDeviceToHost)); 

我想我要问的是什么,莫非是调用内核函数论腐败在某种程度上这些参数相同的参数多次?

由于

+0

你是否反转了你发布的两个代码示例? – talonmies

+0

如果您正在将数据写入'ret_dev'的相同位置,则下一次内核调用将覆盖先前的数据。所以是的,你必须在每次迭代中复制数据。 – sgarizvi

+0

好吧,因为我不是在'ret_dev'的同一位置上写的,所以我不需要在每次迭代中都复制它,对吧? – vegeta

回答

0

当启动一个内核多次(或多个内核)而没有指定的流,它们被排队在标准流0,并连续执行。 memcpy调用的帐户相同。这些内核和memcpy调用的顺序将被保留。此外,内核参数总是按值传递,稍后更改值不会破坏已安排的调用,即使它尚未启动。

无论是否可以将memcpy移出循环,都取决于内核的功能。如果所有内核都在自己的数据块上工作,那么在启动所有内核之后,您应该很好地复制结果。在这种情况下,您可能需要检查算法是否需要全局同步,因为如果不是,则可以通过在内核中移动for循环来获得大量速度。

如果你的内核在所有的数据上工作,你需要在特定的时间保存它,你仍然可以考虑在gpu上分配一个额外的结果数组,并将它复制到内核中。这也应该比在循环中执行memcpy更快。