【问题标题】:CUDA and shared variables among different global functionsCUDA 和不同全局函数之间的共享变量
【发布时间】:2012-12-14 15:27:42
【问题描述】:

只是对 CUDA 的一些疑问。也许他们可能看起来很愚蠢的问题;对此我深表歉意。

如果我在 GPU 上声明一个变量(例如,具有 N 个元素的数组 alphacudaMalloc((void**)&alpha, N * sizeof(double)))并在全局函数中分配它的值而不释放它内存,这个变量应该可以用于其他后续的全局函数吧?

此外,是否可以(或可取)在 GPU 上计算一个标量变量并使其在 GPU 上的多个全局函数之间共享,还是每次都将它作为来自 CPU 的参数传递更好?

感谢您的关注。

【问题讨论】:

  • 感谢您的所有回答。我无法在 GPU 上计算我的所有项目,因为我有一个递归循环。因此,我的目标是在此循环之外的 GPU 上计算一些常量数组,而不释放所使用的内存,以及 CPU 上的一些常量标量。然后,在递归循环中,我将尽可能使用全局函数。

标签: cuda global-variables


【解决方案1】:

是的,如果您将值写入已分配的全局内存中,这些值将一直存在,直到您释放该内存为止,即使跨内核调用也是如此。

对于访问标量变量(即常量),更好的方法是将其作为参数传递给全局内核启动,而不是将其放入全局内存并从那里读取。全局内存访问成本很高,这样可以避免每次需要读取时从全局内存中加载该标量。

【讨论】:

  • 内核参数也存储在全局内存中,但它们是通过常量缓存读取的。如果参数是指向数组的指针,也可以通过内核参数列表中的const限定符通过常量缓存读取数组本身。
【解决方案2】:

如果我的问题没有错,那么您正在分配一个数组,将数组填充到 GPU 上的全局内核函数中,然后在另一个内核调用中处理该数组的值。

只要不释放分配的数组,它的值就会保留在全局内存中。因此,您可以这样做并处理相同的数组,而无需将其复制回 CPU。当您有执行时间限制或其中一个内核函数在库中时,在多个内核调用之间划分作业可能会很方便。但在大多数其他情况下,在一个函数调用中完成所有工作似乎更好。

将标量值作为参数传递似乎更好,因为从全局内存中读取它的开销非常高。

【讨论】:

    【解决方案3】:

    如果我在 GPU 上声明一个变量(例如,具有 N 个元素的数组 alpha,cudaMalloc((void**)&alpha, N * sizeof(double)))并在全局函数中分配其值而不释放其内存,这个变量应该可以用于其他后续的全局函数吧?

    您不能从全局函数(内核)调用cudaMalloc()。这是一个主机功能。您可以在内核中使用malloc()new,但这可能效率低下。

    您可以在多个内核中使用相同的数组,例如,您可以使用不同的内核执行多个计算步骤。

    此外,是否可以(或可取)在 GPU 上计算一个标量变量并使其在 GPU 上的多个全局函数之间共享,还是每次都将它作为来自 CPU 的参数传递更好?

    如果您将常量作为参数传递给内核,它会在所有线程之间非常有效地共享。因此,在 CPU 上计算参数并将其传递给内核通常效率更高。

    如果在创建标量时需要进行大量并行计算,那么最好使用单独的内核进行计算,将其传回主机,然后将其作为参数传递给下一个内核。替代方案只会增加代码的复杂性,而不会带来任何性能优势。

    如果标量所需的计算量很少,那么使用内核计算它是没有意义的。另外,请记住,无法保证在内核中启动块的顺序,因此您必须在内核中创建一个单独的代码路径来设置标量,然后进行昂贵的线程索引测试和同步来计算标量并使其可用于所有线程。

    【讨论】:

    • 谢谢。关于 cudaMalloc() 的使用,我的问题没有解释清楚,但我的意思是你说的(即在主函数中分配 GPU 上的内存空间,而不是在全局中)。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 2016-12-12
    • 2015-03-28
    • 2018-12-22
    相关资源
    最近更新 更多