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