我有一个相当大而复杂的 CUDA 代码,它对于大量块/线程非常可靠地挂起。我试图弄清楚代码的确切位置。
当我在cuda-gdb
中运行代码时,我可以看到哪些线程/块挂起,但我看不到"虚拟PC"之外的位置。
如果我使用"-G"编译代码以获取调试信息,无论我运行多长时间,它都会运行得慢得多并且拒绝挂起。
有没有办法将"虚拟PC"映射到源代码中的一行代码,甚至是大约?或者有没有办法在不关闭所有优化的情况下获取调试信息?
我尝试使用"-G3",但无济于事。这只是给了我"nvcc warning : Setting optimization level to 0 as optimized debugging is not supported
"类型的警告。我正在使用 CUDA 编译工具版本 4.1。
好的,我想我已经自己想通了。
如果cuobjdump
在路径中,则在 cuda-gdb
中,命令x $pc
将为您提供当前线程停止的汇编程序。问题是,如果源代码不是用-G
编译的,您将无法将汇编语句与代码中的一行相关联。
要将汇编程序与内核代码匹配,首先请确保使用 nvcc -keep [..] mykernel.cu
编译内核。这应该生成文件mykernel.sm_20.cubin
(或您选择的任何拱门(并mykernel.ptx
.
要获取整个内核的汇编程序,请运行 cuobjdump -sass mykernel.cubin > output.ptx
。在 cuda-gdb
中,x/20i $pc-80
获取一些上下文,并在文件output.ptx
中查找这些行。然后,您可以尝试将这些行与 mykernel.ptx
中的 PTX 代码匹配,其中包含引用源中该行.loc
语句。
这种方法需要一点创造力来匹配来自 cubin 文件的 PTX 和来自 nvcc
的 PTX,因为指令可能会被重新排序。在我的代码中,我有一大块FFMA
指令,我可以寻找来了解我的方位。您可以使用"output.ptx"从调试器中找到确切的行,然后在相同的相对位置查找"mykernel.ptx"。
这一切都涉及相当多的工作,但它确实允许您缩小"虚拟PC"在原始源中的位置。