我使用 CUDA 6.5 和 4 x GPU Kepler 。
我使用多线程,CUDA运行时API以及从不同CPU线程访问CUDA上下文(通过使用OpenMP - 但这并不重要)。
当我调用cudaDeviceSynchronize();
时,是否会等待内核仅在最新调用cudaSetDevice()
或所有CUDA上下文中选择的当前CUDA上下文中完成?
如果它将等待内核在所有CUDA上下文中完成,那么它将在当前CPU线程中使用的所有CUDA上下文中等待(示例CPU中的 CPU_0将等待GPU:0和1 )或通常所有CUDA上下文( CPU thread_0将等待GPU:0,1,2和3 )?
以下代码:
// For using OpenMP requires to set:
// MSVS option: -Xcompiler "/openmp"
// GCC option: –Xcompiler –fopenmp
#include <omp.h>
int main() {
// execute two threads with different: omp_get_thread_num() = 0 and 1
#pragma omp parallel num_threads(2)
{
int omp_threadId = omp_get_thread_num();
// CPU thread 0
if(omp_threadId == 0) {
cudaSetDevice(0);
kernel_0<<<...>>>(...);
cudaSetDevice(1);
kernel_1<<<...>>>(...);
cudaDeviceSynchronize(); // what kernel<>() will wait?
// CPU thread 1
} else if(omp_threadId == 1) {
cudaSetDevice(2);
kernel_2<<<...>>>(...);
cudaSetDevice(3);
kernel_3<<<...>>>(...);
cudaDeviceSynchronize(); // what kernel<>() will wait?
}
}
return 0;
}
答案 0 :(得分:7)
当我调用cudaDeviceSynchronize()时;它会等待内核吗? 仅在最近通话选择的当前CUDA上下文中完成 cudaSetDevice(),还是在所有CUDA上下文中?
cudaDeviceSynchronize()
只会将主机与当前设置的GPU同步,如果正在使用多个GPU并且所有GPU都需要同步,则必须为每个GPU单独调用cudaDeviceSynchronize()
。
这是一个最小的例子:
cudaSetDevice(0); cudaDeviceSynchronize();
cudaSetDevice(1); cudaDeviceSynchronize();
...
因此,答案是cudaDeviceSynchronize()
仅在当前CUDA上下文中同步所有流
来源:Pawel Pomorski,多个GPU上的CUDA幻灯片&#34;。已关联here。