是否有必要在对 CUDA 内核的两次调用之间使用同步?

Is it necessary to use synchronization between two calls to CUDA kernels?

到目前为止,我编写的程序中内核只被调用一次

所以我有一个内核

__global__  void someKernel(float * d_in ){  //Any parameters
//some operation
}

我基本上也是

main()
{
   //create an array in device memory
   cudaMalloc(......);
   //move host data to that array
   cudaMemcpy(......,cudaMemcpyHostToDevice);
   //call the kernel
   someKernel<< <nblocks,512>> >(.......);
   //copy results to host memory
   cudaMemcpy(......,cudaMemcpyDeviceToHost);

//  Point to notice HERE
}

它工作正常。然而这次我不仅要调用内核一次,还要调用多次 像

main()
{
   //create an array in device memory
   cudaMalloc(......);
   //move host data to that array
   cudaMemcpy(......,cudaMemcpyHostToDevice);
   //call the kernel
   someKernel<< <nblocks,512>> >(.......);
   //copy results to host memory
   cudaMemcpy(......,cudaMemcpyDeviceToHost);


// From here
//Some unrelated calculations here
 dothis();
 dothat();
//Then again the kernel repeteadly
 for(k: some_ks)
   {
     // Do some pre-calculations

     //call the kernel
     someKernel<< <nblocks,512>> >(.......);
      
    // some post calculations  

   }
}

我的问题是我是否应该在第一次调用内核和在 for 循环(以及每次迭代)中调用内核之间使用某种同步 也许 cudaDeviceSynchronize 或其他?或者没有必要?

在这种情况下,至少有两个原因不需要额外的同步。

  1. cudaMemcpy 已经是 synchronizing 调用了。它会阻塞 CPU 线程并等待直到所有先前发给该设备的 CUDA activity 完成,然后才允许数据传输开始。数据传输完成后,允许 CPU 线程继续。

  2. 发给单个设备的 CUDA activity 不会以任何方式重叠,除非使用 CUDA streams。您没有使用流。因此,即使是向设备发出的异步工作也会按发出顺序执行。按该顺序发给设备的项目 A 和 B 不会相互重叠。项目 A 将在项目 B 允许开始之前完成。这是一个主要的 CUDA 流语义点。