“nvprof”结果中的“GPU 活动”和“API 调用”有什么区别?
不知道为什么同一个函数会有时差。例如,[CUDA memcpy DtoH] 和 cuMemcpyDtoH。
所以我不知道什么时候合适。我必须写一个测量,但我不知道该使用哪个。
活动是 GPU 对某些特定任务的实际使用。
活动可能正在运行内核,或者可能正在使用 GPU 硬件将数据从主机传输到设备,反之亦然。
这种“活动”的持续时间是通常意义上的持续时间:这个活动什么时候开始使用 GPU,什么时候停止使用 GPU。
API 调用是由您的代码(或由您的代码进行的其他 CUDA API 调用)对 CUDA 驱动程序或运行时库的调用。
这两者当然是相关的。您可以通过某种 API 调用来启动 GPU 上的活动。这适用于数据复制和运行内核。
但是,“持续时间”或报告时间可能有所不同。例如,如果我启动一个内核,可能有很多原因(例如,在同一流中尚未完成的先前活动)导致内核没有“立即”开始执行。从 API 的角度来看,内核“启动”可能比内核的实际运行时间持续更长的时间。
这也适用于 API 使用的其他方面。例如,cudaDeviceSynchronize()可能需要很长时间或很短的时间,具体取决于设备上正在发生的事情(活动)。
通过研究 NVIDIA 视觉分析器 (nvvp) 中的时间线,您可能会更好地了解这两种报告类别之间的区别。
让我们以您的具体案例为例。这似乎是一个与驱动程序 API 相关的应用程序,并且您显然有一个内核启动和(我猜)内核启动后立即执行 D->H memcpy 操作:
multifrag_query_hoisted_kernels (kernel launch - about 479ms)
cuMemcpyDtoH (data copy D->H, about 20us)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,由于 CUDA 内核启动是异步的,主机代码将启动内核,然后它会继续下一个代码行,这是一个cuMemcpyDtoH调用,这是一个阻塞调用。这意味着调用会导致 CPU 线程在那里等待,直到前一个 CUDA 活动完成。
分析器的活动部分告诉我们内核持续时间约为 479 毫秒,复制持续时间约为 20 微秒(短得多)。从活动持续时间的角度来看,这些时间是相关的。但是,从主机CPU线程来看,主机CPU线程“启动”内核所需的时间远短于479ms,主机CPU线程完成调用cuMemcpyDtoH并进行下一行所需的时间代码比 20us 长得多,因为它必须在那个库调用那里等待,直到之前发布的内核完成。这两者都是由于 CUDA 内核启动的异步特性,以及cuMemcpyDtoH.