CUDA:为啥会有大量的 GPU 空闲时间?
Posted
技术标签:
【中文标题】CUDA:为啥会有大量的 GPU 空闲时间?【英文标题】:CUDA: why is there a large amount of GPU idle time?CUDA:为什么会有大量的 GPU 空闲时间? 【发布时间】:2012-08-26 20:57:01 【问题描述】:问题
总 GPU 时间 + 总 CPU 开销小于总执行时间。为什么?
详情
我正在研究全局内存访问和内核启动对性能的影响程度,我设计了一个包含多个小内核和总共约 10 万个内核调用的代码。每个内核从全局内存中读取数据,处理它们,然后写回全局内存。正如预期的那样,代码运行速度比只有一个大内核和很少内核启动的原始设计慢得多。
问题出现在我使用命令行分析器获取 "gputime"(GPU 内核或内存复制方法的执行时间)和 "cputime"(CPU 开销对于非阻塞方法,阻塞方法的 gputime 和 CPU 开销之和)。据我了解,所有 gputime 和所有 cputime 的总和应该超过整个执行时间(最后一个 "gpuendtimestamp" 减去第一个 "gpustarttimestamp"),但事实证明反之亦然(gputimes 之和=13.835064 s, cputimes 总和=4.547344 s,总时间=29.582793)。在一个内核的结束和下一个内核的开始之间,往往有大量的等待时间,大于下一个内核的 CPU 开销。遇到这个问题的内核大多是:memcpyDtoH、memcpyDtoD 以及 launch_closure_by_value、fast_scan 等推力内部函数,大概是什么原因?
系统 Windows 7,TCC 驱动,VS 2010,CUDA 4.2
感谢您的帮助!
【问题讨论】:
这可能是分析(会增加延迟)和 Windows WDDM 子系统的组合。为了克服后者的高延迟,CUDA 驱动程序对 GPU 操作进行批处理,并通过单个 Windows 内核调用将它们分组提交。如果 CUDA API 命令位于未提交的批处理中,这可能会导致 GPU 长时间处于不活动状态。 谢谢,@talonmies。我刚刚用 smi 检查了 gpu 设置,发现驱动程序模式已经在 TCC 中。我还用环境变量 COMPUTE_PROFILE=0 单独运行了可执行文件,总执行时间保持不变 XS。 在您的问题中没有提及您正在使用 TCC 驱动程序是一个很大的遗漏。我使用 Linux 进行开发,与不进行分析相比,分析增加了 15-40% 的额外执行时间。大部分额外时间是空闲 GPU 时间,而事件由驱动程序和计数器设置、读取和重置处理。 这个问题已经有 3.5 年历史了 - 没有提供任何代码或严肃的分析数据,也无法根据 2012 年发布的内容提供有用的答案。我已投票关闭这些问题原因。 【参考方案1】:这可能是性能分析(会增加延迟)和 Windows WDDM 子系统的组合。为了克服后者的高延迟,CUDA 驱动程序对 GPU 操作进行批处理,并通过单个 Windows 内核调用将它们分组提交。如果 CUDA API 命令位于未提交的批处理中,这可能会导致 GPU 长时间处于不活动状态。
(复制@talonmies 对答案的评论,以启用投票和接受。)
【讨论】:
CUDA 驱动程序在 WDDM 上批处理请求。 Nsight Visual Studio Edition 的下一个版本将显示此行为。此外,这些工具确实会增加开销(每次 API 调用约 1 微秒,每次启动约 5-15 微秒)。对于内核启动,显示的时间只是内核执行的时间。这不包括设置开销。设置时间与您传递的参数数量(CC 2.0+ 上最多 4KB)、纹理/表面绑定以及状态更改的数量(例如缓存配置)有关。 Nsight VSE 和 Visual Profiler 5.0 比 CUDA 命令行分析器更准确且开销更少。 设置开销不是已经包含在命令行分析器报告的cputime 中了吗?现在我还是不太明白为什么 gputime(only the kernel execution time on gpu) + cputime (overhead) @KingCrimson cputime 由命令行分析器报告,包括在驱动程序 API(而不是 CUDA 运行时 API)中花费的大部分时间。除了 CPU 开销之外,GPU 端(不在 gputime 中)还没有考虑到开销。您可以通过简单地增加传递给每次启动的参数数量来观察这一点。命令行分析器将每 128 到 256 个任务转储一次记录。这将增加 CPU 开销。我建议您使用 Nsight VSE,因为开销较小,并且时间线显示与工具相关的开销。 @KingCrimson 如果您发布代码,我可以运行跟踪并为您提供更多信息。 非常感谢@GregSmith。我会问我的主管是否允许发布代码。顺便说一句,我刚刚使用 Nsight VSE 和最新的 nvprof 再次运行跟踪。计时结果(总kernel执行时间,总执行时间)与命令行分析器产生的相同。更复杂的是,Nsight VSE 报告的一些设备到设备内存复制时间是负值。也许某些计数器以某种方式溢出。以上是关于CUDA:为啥会有大量的 GPU 空闲时间?的主要内容,如果未能解决你的问题,请参考以下文章
为啥启动 Numba cuda 内核最多可使用 640 个线程,但在有大量可用 GPU 内存时却因 641 而失败?