使用或不使用选项 -g -G 编译CUDA程序有何区别?

3
我有一个CUDA程序,如果我使用-g -G选项编译该程序,我可以获得正确的输出。如果我没有使用-g -G选项编译它,我不总是得到正确的输出。我的猜测是没有-g -G选项,编译器将优化程序并导致竞争条件。可以有人确认这一点,并让我知道如果我不使用-g -G选项编译程序,应该怎么做才能产生正确的输出。谢谢。
操作系统:x86_64 GNU / Linux CUDA版本:4.0 设备:Geforce 200,它是连接到机器上的GPU之一,我认为它不是显示设备。
1个回答

4
-G 选项可以为设备代码生成调试符号,并禁用设备代码的优化。-g 是主机编译器的一个选项,它启用了为主机代码生成调试符号(并可能禁用主机代码优化)。
这很可能指向你的代码中存在竞态条件,在禁用优化时会被消除。例如,你可能在设备代码中缺少了一个__syncthreads(),这将使代码正确。如果没有它,编译器可能会移动负载或存储操作,导致生成不正确的结果。如果未跨越屏障(__syncthreads()),这种代码移动是一种完全有效的优化。当你指定 -G 时,这样的优化可能被禁用,因此竞争条件不会出现。
首先,请确保失败的是 GPU 代码而不是 CPU 代码,方法是禁用 GPU 调试(删除-G),但启用 CPU 调试(保留-g)。
然后,将问题缩小到特定的内核(缩小范围的过程取决于程序)。检查这个内核,看看是否需要同步(共享内存依赖是常见情况),但却没有同步。
如果你找不到问题所在,但你可以将其缩小到获取错误结果的特定内核,尝试在此处共享内核代码,以便其他人可以帮助你找到问题。

3
另一个可能性(不一定特定于CUDA)是存在未初始化的变量,这些变量在调试与发布版本的代码中产生不同的值,从而影响程序的行为。 - Jared Hoberock
是的,我简直不敢相信自己没想到。这是“只在调试版本中有效”的 bug 最常见的原因... - harrism

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接