当 NaN 仅在使用优化编译时出现时,如何开始调试数字代码?
Posted
技术标签:
【中文标题】当 NaN 仅在使用优化编译时出现时,如何开始调试数字代码?【英文标题】:How to start debugging numerical code, when NaN's appear only when compiled with optimizations? 【发布时间】:2012-04-13 13:13:38 【问题描述】:什么时候开始调试数字代码的一般策略是:
使用激进的优化标志编译的代码,在输出中产生偶尔的 NaN 和 Inf 用-g
(暗示-O0
)编译的代码在调试器上运行,不再产生NaN和Inf了?
在这种情况下,我使用的是 Portland Group C++ 编译器 pgCC,并使用了优化选项
-w -fast -O3 -Mipa=fast -Mfprelaxed -Minline=levels:10
然后只是
-w -g
用于调试版本。但我确信g++
也会发生类似的情况。
编辑:添加打印语句不是一个非常诱人的选项,因为代码不是我写的,它有几千行,我不知道缩小搜索范围; NaN 可能几乎来自任何地方。
【问题讨论】:
可以添加打印语句吗? 如果正确性比速度更重要,请远离您无法控制的优化。 Alex:最好在源代码中找到可疑行,以便能够查看它们,并确定它们是否正确。 这不是可疑的行,而是当你的数值精度有限时,交换律和分配律的常规数学定律停止工作,并且当编译器在假设法律仍然有效,你开始得到奇怪的结果。 【参考方案1】:我会尝试看看你是否可以启用浮点异常like done here,然后看看是否有一些信号 nan 引发了异常。您的编译器中可能有一些编译器标志来启用这些异常。
除此之外,我会进行手动二进制搜索。也就是说,编写一个转储所有变量的函数。然后将程序分成两半,不是按代码行,而是按实际运行的内容,并将其隔离。换句话说,卷起袖子进去吧。
编辑:这可能不适用于您的情况,因为我给您的链接非常特定于 Win32。但也许它会给你一些线索。或者您可以在免费的 MS 编译器上试用该代码?
【讨论】:
+1: Wolf Fence in Alaska(又名二分搜索)在正确使用时非常有效。 20 次通过将使您的问题空间减少 2^20 或 1,000,000+。它在处理包含优化编译器的类 Black Box® 问题时特别有用。【参考方案2】:Portland Group 编译器提供了一些选项来配合指令 -Mfprelaxed
;我会尝试一个一个地设置这些,看看哪些会有所作为。您可能只想从编译中完全删除此指令。
【讨论】:
【参考方案3】:我想指出,在 g++ 的情况下,-g 标志不会抑制优化(也就是说,它并不意味着 -O0)。包含调试信息的优化可执行文件更难调试,但它当然可以这样做。
【讨论】:
以上是关于当 NaN 仅在使用优化编译时出现时,如何开始调试数字代码?的主要内容,如果未能解决你的问题,请参考以下文章