Cuda 在两个GPU上运行的代码不会达到并发执行,并且具有无关的加速比
我有这样的代码:Cuda 在两个GPU上运行的代码不会达到并发执行,并且具有无关的加速比,cuda,gpgpu,multi-gpu,Cuda,Gpgpu,Multi Gpu,我有这样的代码: for(int i =0; i<2; i++) { //initialization of memory and some variables ........ ........ RunDll(input image, output image); //function that calls kernel } for(inti=0;i在你的评论中,你说: RunDll有两个内核,它们正在逐个启动。内核确实有cudaThreadSynchr
for(int i =0; i<2; i++)
{
//initialization of memory and some variables
........
........
RunDll(input image, output image); //function that calls kernel
}
for(inti=0;i在你的评论中,你说:
RunDll有两个内核,它们正在逐个启动。内核确实有cudaThreadSynchronize()
请注意,cudaThreadSynchronize()
相当于cudaDeviceSynchronize()
(前者实际上是),这意味着您将在一个GPU上运行,同步,然后在另一个GPU上运行。还请注意,cudaMemcpy()
是一个阻塞例程,您需要cudaMemcpyAsync()
避免所有阻塞的版本(正如@Jackolanten在评论中指出的)
一般来说,您需要发布更多关于RunDLL()
内部内容的详细信息,因为如果没有这些信息,您的问题就没有足够的信息来给出明确的答案。最好遵循。在我对您上一篇文章的回答中(),我指出当使用2
GPU时,您不会实现2
的加速
解释为什么,让我们考虑下面的代码片段
Kernel1<<<...,...>>>(...); // assume Kernel1 takes t1 seconds
// assume CPUFunction + cudaMemcpys take tCPU seconds
cudaMemcpy(...,...,...,cudaMemcpyDeviceToHost); // copy the results of Kernel1 to CPU
CPUFunction(...); // assume it takes tCPU seconds
cudaMemcpy(...,...,...,cudaMemcpyHostToDevice); // copy data from the CPU to Kernel2
Kernel2<<<...,...>>>(...); // assume it takes t2 seconds
Kernel1(…);//假设Kernel1需要t1秒
//假设CPUFunction+cudaMemcpys需要tCPU秒
cudaMemcpy(…,…,…,cudaMemcpyDeviceToHost);//将内核1的结果复制到CPU
cpuffunction(…);//假设需要tCPU秒
cudaMemcpy(…,…,…,cudamemcpyhostodevice);//将数据从CPU复制到内核2
Kernel2(…);//假设需要2秒
无论我是使用cudaDeviceSynchronize()
还是cudaMemcpy
来获得同步
在一个GPU上的for
循环中执行上述代码片段的成本仅为
t1+tCPU+t2+t1+tCPU+t2=2t1+2tCPU+2t2
在2
GPU的情况下,如果您能够在两个不同的GPU上实现Kernel1
和Kernel2
的完美并发执行,那么执行上述代码片段的成本将是
t1(在两个GPU上并发执行Kernel1
)+2*tCPU(需要对CPU函数进行两次调用,每个调用用于Kernel1
输出的不同实例)+t2(在两个GPU上并发执行Kernel2
)
因此,使用两个GPU而不是一个GPU实现的加速比将是
(2*(t1+tCPU+t2))/(t1+2tCPU+t2)
当tCPU等于零时,加速比变为2
这是的一个表达式。您需要提供更多有关RunDll
实际功能的详细信息。如果它包含阻止API调用,则很可能会发生序列化。RunDll有两个内核,它们将逐个启动。内核确实有cudaThreadSynchronize()
和\uu syncthreads()
。但我没有使用cudaDeviceSynchronize()
代码中的任何地方。你说阻止API还有什么意思?昨天你发布了一个问题,在这个问题中,你提到了每个循环的中非并发运行的CPU函数和内核。这是同一个问题吗?此外,你被要求提供有关RunDll
函数的更多详细信息,但你的编辑没有cudaThreadSynchronize()
相当于cudaDeviceSynchronize()
(而前者实际上已被弃用-)当然可以,但如果在启动一个和另一个的工作之间进行同步,则不能。如果希望异步运行,则只能在RunDLL
中进行异步调用。您已更新了问题的详细信息,但实际上仍然没有提供足够的信息,因为没有关于您在中所做操作的信息de>RunBasicFP_CUDA
。
Kernel1<<<...,...>>>(...); // assume Kernel1 takes t1 seconds
// assume CPUFunction + cudaMemcpys take tCPU seconds
cudaMemcpy(...,...,...,cudaMemcpyDeviceToHost); // copy the results of Kernel1 to CPU
CPUFunction(...); // assume it takes tCPU seconds
cudaMemcpy(...,...,...,cudaMemcpyHostToDevice); // copy data from the CPU to Kernel2
Kernel2<<<...,...>>>(...); // assume it takes t2 seconds