【问题标题】:CUDA calling kernel function multiple times on the same argumentsCUDA 在相同的参数上多次调用内核函数
【发布时间】:2018-02-21 13:07:29
【问题描述】:

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

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

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

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

谢谢

【问题讨论】:

  • 您是否将您发布的两个代码示例颠倒过来?
  • 如果你正在将数据写入ret_dev的相同位置,那么下一次内核调用将覆盖之前的数据。所以是的,你必须在每次迭代中复制数据。
  • 好的,因为我没有写在ret_dev的同一个位置,所以我不需要在每次迭代中复制它,对吧?
  • @talonmies:我都试过了,现在我看到了相同的结果,但我想知道可能会有一些问题......
  • @user1961040:我的意思是,在你的问题中,“循环外”代码在循环内有一个 memcpy,而“循环内”在循环外有一个 memcpy

标签: cuda


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    相关资源
    最近更新 更多