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