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

Kan*_*bot 1 c++ cuda

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

所以我有一个内核

__global__  void someKernel(float * d_in ){  //Any parameters
//some operation
}
Run Code Online (Sandbox Code Playgroud)

我基本上是这样做的

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
}
Run Code Online (Sandbox Code Playgroud)

它工作正常。但是这次我想不仅一次而且多次调用内核 类似

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  

   }
}
Run Code Online (Sandbox Code Playgroud)

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

Rob*_*lla 7

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

  1. cudaMemcpy已经是一个同步调用。它会阻塞 CPU 线程并等待所有先前发送给该设备的 CUDA 活动完成,然后才允许开始数据传输。一旦数据传输完成,就允许 CPU 线程继续进行。

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