【问题标题】:cuda infinite kernelcuda 无限内核
【发布时间】:2012-05-13 06:06:11
【问题描述】:

我正在开发一个需要无限期运行 CUDA 内核的应用程序。我有一个 CPU 线程将 stg 写入列表,而 gpu 读取该列表并重置(至少在开始时)。当我在内核中写代码时

while(true)
{
//kernel code
}

系统挂断。我知道 GPU 仍在处理,但当然没有任何反应。而且我不确定列表中的重置是否会发生。

不得不提的是,用于计算的GPU不用于显示,所以没有看门狗问题。

操作系统是 Ubuntu 11.10 和 cuda 工具包 4.1。 我可以使用任何帮助/示例/链接来成功编写无限内核。

【问题讨论】:

  • CUDA 调度程序在处理无限循环、自旋锁等方面确实很糟糕,因为这些“对象”对于 GPU 架构来说是完全陌生的。更常见和可预测的方法是偶尔运行一次内核以检查是否出现了新元素。
  • 另外,新元素不能随便出现。你必须把它们放在那里。所以你知道什么时候需要重新运行内核。
  • 当内核运行时,高端 GPU 的功耗可能会增加 250W,因此通过选择何时运行内核可以节省资金。也更环保。
  • "无限内核对于当前项目是强制性的。目标是一个 gpu 控制器,因此 gpu 必须在没有 cpu 干扰的情况下自主工作(当然内核调用除外)。"你的整个想法听起来完全有缺陷 IMO。你应该回去仔细重新考虑一下。记住我之前所说的:新元素不能随便出现。你必须把它们放在那里。所以你知道什么时候需要重新运行内核。
  • 对于您的问题,您希望在后台运行一个完整的进程或至少一个线程,而不仅仅是一个 CUDA 内核。

标签: debugging cuda infinite


【解决方案1】:

CUDA 编程语言和 CUDA 架构目前不支持无限内核。我建议你考虑一下 Roger 的建议。

如果你想这样做,我建议你在你的内核中添加以下调试代码:

  1. 每 N 个时钟在固定内存中增加一个变量(可能希望每个 SM 有不同的位置),并且,
  2. 定期读取可由 CPU 更新的内存位置,以告知内核退出。

这是一个软件看门狗。

您可以使用 clock() 或 clock64() 来控制执行 (1) 和 (2) 的频率。

您可以使用 cuda-gdb 来调试您的问题。

该语言不支持无限循环。编译器可能正在剥离代码。您可能需要查看 PTX 和 SASS。如果编译器生成错误代码,您可以通过让编译器认为存在有效的退出条件来伪造它。

【讨论】:

  • 这是一个聪明的建议,但没有奏效。即使我删除 while(true) 并将其替换为 (for int i=0; i
  • 如果您将数据保存在固定的系统内存中,请确保您正在执行 __theradfence_system 以刷新对系统内存的写入。如果您正在读取一个值,请确保将其标记为 volatile,这样编译器就不会使用先前读取的寄存器。
【解决方案2】:

正如@Greg Smith 已经指出的那样,CUDA 编译器不会为无限循环生成正确的程序集。当然,在某些情况下它是一个完美的解决方案,例如运行一个后台服务内核,它从主机接收更新,推送到主机映射内存。

一种解决方法,从 CUDA 9.2 开始有效:

volatile int infinity = 1;
while (infinity)
{
  ...
}

在发散分支内进行无限循环显然不是一个好主意。除此之外,while (1) 构造 IMO 的不当处理绝对是一个错误。

【讨论】:

    猜你喜欢
    • 2012-08-23
    • 2022-01-14
    • 1970-01-01
    • 2021-02-07
    • 2013-03-17
    • 2011-10-22
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多