当 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 仅在使用优化编译时出现时,如何开始调试数字代码?的主要内容,如果未能解决你的问题,请参考以下文章

仅在WinXP计算机上安装WiX时出现错误2259

编译器指令 - 建议 - 仅在调试模式下运行代码

为啥我会收到错误“不安全代码可能仅在使用 /unsafe 编译时出现”?

仅在调试代码时出现进程中的 hsqldb 错误

NaN 通过矩阵分解

如何解决loss NAN的问题