0

我尝试搜索一个类似的问题,但找不到一个,尽管有几个标题相似。

我在主机上有这样的代码:

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));

我想我想问的是,在同一个参数上多次调用内核函数是否会以某种方式破坏这些参数?

谢谢

4

1 回答 1

0

当您多次(或多个内核)启动内核而不指定流时,它们会在标准流 0 上排队并连续执行。memcpy 调用也是如此。这些内核和 memcpy 调用的顺序将被保留。此外,内核参数始终按值传递,并且稍后更改值不会破坏已调度的调用,即使它尚未启动。

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

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

于 2013-02-08T14:24:23.323 回答