“nvprof”的结果中的“GPU 活动”和“API 调用”有啥区别?

Posted

技术标签:

【中文标题】“nvprof”的结果中的“GPU 活动”和“API 调用”有啥区别?【英文标题】:What is the difference between 'GPU activities' and 'API calls' in the results of 'nvprof'?“nvprof”的结果中的“GPU 活动”和“API 调用”有什么区别? 【发布时间】:2019-04-08 13:00:03 【问题描述】:

“nvprof”结果中的“GPU 活动”和“API 调用”有什么区别?

不知道为什么同一个函数会有时间差。 例如,[CUDA memcpy DtoH] 和 cuMemcpyDtoH。

所以我不知道什么是正确的时间。 我必须写一个测量,但我不知道该使用哪个。

【问题讨论】:

【参考方案1】:

活动是 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)

在这种情况下,由于 CUDA 内核启动是异步的,因此主机代码将启动内核,然后继续执行下一行代码,即 cuMemcpyDtoH 调用,这是一个阻塞 打电话。这意味着调用会导致 CPU 线程在那里等待,直到之前的 CUDA 活动完成。

分析器的活动部分告诉我们内核持续时间约为 479 毫秒,复制持续时间约为 20 微秒(短得多)。从活动持续时间的角度来看,这些是相关的时间。但是,从宿主 CPU 线程来看,宿主 CPU 线程“启动”内核所需的时间远小于 479ms,宿主 CPU 线程完成对cuMemcpyDtoH 的调用并继续执行的时间下一行代码比 20us 长得多,因为它必须在那里等待库调用,直到之前发布的内核完成。这两者都是由于 CUDA 内核启动的异步性质以及cuMemcpyDtoH 的“阻塞”或同步性质。

【讨论】:

以上是关于“nvprof”的结果中的“GPU 活动”和“API 调用”有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

分析结果不会出现在事件/指标摘要模式 nvprof

计算器和 nvprof 之间的占用不同

使用 CUDA Profiler nvprof 进行内存访问

如何仅通过 nvprof 分析 CUDA 应用程序

为啥 nvprof 没有浮点除法运算的指标?

带宽的 nvprof 选项