只是对CUDA的一些疑问。也许他们可能看起来很愚蠢的问题;我为此道歉。
如果我在 GPU 上声明一个变量(例如,具有N个元素的数组alpha , )并在全局函数中分配其值而不释放其内存,则该变量应该可用于其他连续的全局函数,对吗?cudaMalloc((void**)&alpha, N * sizeof(double))
此外,是否可以(或建议)在 GPU 上计算一个标量变量并使其在 GPU 上的多个全局函数之间共享,还是每次都将它作为来自 CPU 的参数传递更好?
感谢您的关注。
只是对CUDA的一些疑问。也许他们可能看起来很愚蠢的问题;我为此道歉。
如果我在 GPU 上声明一个变量(例如,具有N个元素的数组alpha , )并在全局函数中分配其值而不释放其内存,则该变量应该可用于其他连续的全局函数,对吗?cudaMalloc((void**)&alpha, N * sizeof(double))
此外,是否可以(或建议)在 GPU 上计算一个标量变量并使其在 GPU 上的多个全局函数之间共享,还是每次都将它作为来自 CPU 的参数传递更好?
感谢您的关注。
是的,如果您将值写入分配的全局内存,这些值将一直存在,直到您释放该内存,即使跨内核调用也是如此。
至于访问标量变量(它们是常量),更好的方法是将其作为参数传递给全局内核启动,而不是将其放入全局内存并从那里读取。全局内存访问是昂贵的,这避免了每次需要读取全局内存时从全局内存中加载该标量。
如果我的问题是正确的,那么您正在分配一个数组,将数组填充到 GPU 上的全局内核函数中,然后在另一个内核调用中处理该数组的值。
只要您不释放分配的数组,它的值就会保留在全局内存中。因此,您可以这样做并处理相同的数组,而无需将其复制回 CPU。当您有执行时间限制或内核函数之一在库中时,在多个内核调用之间划分作业可能会很方便。但在大多数其他情况下,似乎最好在一个函数调用中完成所有工作。
将标量值作为参数传递似乎也更好,因为从全局内存中读取它的开销非常高。
如果我在 GPU 上声明一个变量(例如,具有 N 个元素的数组 alpha,cudaMalloc((void**)&alpha, N * sizeof(double))) 并在全局函数中分配它的值而不释放它的内存,这个变量应该可用于其他连续的全局功能,对吧?
您不能cudaMalloc()
从全局函数(内核)调用。这是一个主机功能。您可以在内核中使用malloc()
和new
,但这可能效率低下。
您可以在多个内核中使用相同的数组,例如,您可以使用不同的内核执行多个计算步骤。
此外,是否可以(或建议)在 GPU 上计算一个标量变量并使其在 GPU 上的多个全局函数之间共享,还是每次都将它作为来自 CPU 的参数传递更好?
如果您将常量作为参数传递给内核,它会在所有线程之间非常有效地共享。因此,在 CPU 上计算参数并将它们传递给内核通常会更有效率。
如果在创建标量时需要进行大量并行计算,那么最好使用单独的内核进行计算,将其传递回主机,然后将其作为参数传递给下一个内核。替代方案只会增加代码的复杂性,而没有任何性能优势。
如果标量几乎不需要计算,那么用内核计算它是没有意义的。另外,请记住,无法保证在内核中启动块的顺序,因此您必须在内核中创建一个单独的代码路径来设置标量,然后进行昂贵的线程索引测试和同步来计算标量并使其可用于所有线程。