Cuda 内核启动和内核执行之间的时间

Cuda 内核启动和内核执行之间的时间,cuda,profiling,nsight,Cuda,Profiling,Nsight,我正试图通过使用VS2010的并行Nsight 2.1版来优化我的CUDA程序 我的程序在带有GTX 480板的Windows 7(32位)计算机上运行。我已经安装了CUDA 4.1 32位工具包和301.32驱动程序 程序中的一个周期包括将主机数据复制到设备、执行内核以及将结果从设备复制到主机 正如您在下面的分析器结果图中所看到的,内核在四个不同的流中运行。每个流中的内核依赖于“流2”中复制到设备的数据。这就是asyncMemcpy在不同流中启动内核之前与CPU同步的原因 图中让我恼火的是第

我正试图通过使用VS2010的并行Nsight 2.1版来优化我的CUDA程序

我的程序在带有GTX 480板的Windows 7(32位)计算机上运行。我已经安装了CUDA 4.1 32位工具包和301.32驱动程序

程序中的一个周期包括将主机数据复制到设备、执行内核以及将结果从设备复制到主机

正如您在下面的分析器结果图中所看到的,内核在四个不同的流中运行。每个流中的内核依赖于“流2”中复制到设备的数据。这就是asyncMemcpy在不同流中启动内核之前与CPU同步的原因

图中让我恼火的是第一次内核启动结束(10.5778679285)和内核执行开始(10.5781500)之间的巨大差距。启动内核大约需要300人,这在不到1毫秒的处理周期内是一个巨大的开销

此外,内核执行和将结果复制回主机的数据之间没有重叠,这进一步增加了开销


这种行为有什么明显的原因吗?

通过跟踪,我可以看出三个问题

  • Nsight CUDA分析为每个API调用增加约1µs。您同时启用了CUDA运行时和CUDA驱动程序API跟踪。如果您禁用CUDA运行时跟踪,我猜您会将宽度减少50µs

  • 由于您使用的是Windows 7上的GTX 480,因此您使用的是WDDM驱动程序型号。在WDDM上,驱动程序必须进行内核调用以提交工作,这会引入大量开销。为避免减少此开销,CUDA驱动程序在内部软件队列中缓冲请求,并在队列已满时将请求发送给驱动程序,然后通过同步调用刷新。可以使用cudaEventQuery强制驱动程序刷新工作,但这可能会影响其他性能

  • 看起来您正在以深度优先的方式向streams提交工作。在ComputeCapability 2.x和3.0设备上,如果您以广度优先的方式提交到streams,您将获得更好的结果。在您的情况下,您可能会看到内核之间的重叠

  • 时间轴屏幕截图没有为我提供足够的信息来确定为什么内存拷贝在所有内核完成后才开始。给定API调用模式I,您应该能够看到在每个流完成启动后开始传输

    如果您正在等待所有流完成,则执行cudaDeviceSynchronize可能比执行4个cudaStreamSynchronize调用更快

    Nsight的下一个版本将具有其他功能,以帮助理解软件队列以及向计算引擎和内存复制引擎提交工作