2017-05-03 93 views
-1

我的代码有问题,需要调试它。尝试了一切我能想到的,但没有类似于串行调试的调试找不到问题,我的问题归结为:cuda nsight visual studio版内核调试

这是示例代码的一部分,它是如果您创建在VS新的CUDA项目(同这里https://www.youtube.com/watch?v=Ed_h2km0liI),但我的问题是:

enter image description here

我刚加入的线13-18和几个断点,这是描述我的问题。 我怎样才能调试这个内核(让我们说线程1),并让n实际上从0-4迭代,因为像这样,循环似乎迭代(如果我点击继续,它跳过5次断点),但是n总是'n'在目标位置没有值

+0

如果您尝试使用不太重要的示例,会发生什么情况?该循环足够小,以至于它可能无法映射到调试器可以在运行时忠实地表示的代码。 – talonmies

+0

在我的问题代码中,任何在内核函数内部声明的变量在调试过程中都没有任何值,所以我认为我做错了某些事情,并以某种方式调试了主函数(但不明白为什么它会注册循环步骤随着断点) – user3338991

回答

0

这是由于优化。编译器可能会检测到循环的迭代次数不变并且静态展开。事实上,循环可以替换为c[i] = 5,因为唯一可观察的变化是在最后一次迭代中。您可以通过检查生成的PTX来验证(或反驳)该假设。

默认情况下CUDA工具链甚至在调试配置进行一些关键的编译器优化(例如优化寄存器分配有关)

要解决此:

  • 确保您构建和运行调试配置并且优化确实被禁用
  • 确保通过添加以下编译器标志来启用调试符号:

    -g -G 
    
  • 试图通过添加以下编译器标志

    -O0 -Xcompiler -O0 -Xcicc -O0 -Xptxas -O0 -lineinfo 
    

这些标志显著增加二进制文件的大小来禁用优化适用于所有的工具的其余部分,程序是非常缓慢和消耗大量的更多珍贵的寄存器和机载内存(直到程序不能运行)。仅在小块代码上使用,并在必要时用于调试。或者,您可以实现非常量循环边界(例如,在运行时传递的变量),并使循环结果依赖于以前的迭代,这样编译器将失去优化循环的机会。

+0

感谢您的回答,但我似乎无法设置正确的选项。在项目属性(所有配置,所有平台) - >配置属性 - > CUDA C/C++ - >主机上我已将您的编译器标志输入到其他COmpiler选项中。 将相同的选项卡优化设置为禁用,并将主机调试生成为yes(-g)。在设备选项卡中,我生成了GPU调试 - 是(-G)。 构建时,我得到:忽略其他编译器选项中每个选项的未知选项。而n仍然没有价值。对于基本问题抱歉,我只是一个在旅途中学习的业余爱好程序员。 – user3338991

+1

我不相信这是正确的。任何具有nvcc的调试版本都会关闭所有的优化,并且应该发出循环,并且所有符号都指向已经在调试中构建的代码 – talonmies

+0

所以唯一的解决方案是在内核之外传递n?比如在这种情况下只监视c [i] = n(这对调试是可见的)?是不是有一个更简单的解决方案来正确调试内核中的内容,因为只有内核函数内部的变量在VS nsight调试中才可见。 – user3338991