在 Linux for x86 上检测异常浮点操作

Posted

技术标签:

【中文标题】在 Linux for x86 上检测异常浮点操作【英文标题】:Detecting denormal float operations on Linux for x86 【发布时间】:2013-06-20 15:23:29 【问题描述】:

我正在将一个 windows 程序移植到 linux 上,并且被一段特定于 msvc 的代码难住了,这些代码似乎检查了是否存在异常或不精确结果的浮点运算。我非常不确定如何以稳健的方式实现它。我应该补充一点,当涉及到特定于 linux 的编程和此类非常低级的操作时,我相当缺乏经验。

具体来说,给我带来麻烦的部分如下:

  if ( _statusfp() & ( _SW_INEXACT | _SW_DENORMAL) )
  
     ... portable stuff ...
  

  _clearfp();

虽然 fenv.h 似乎提供了清除状态标志和检查不精确标志的能力,但它似乎没有在检查异常标志方面提供任何帮助。此外,我曾向我建议 gcc 可能会以不同的方式处理浮点运算,以至于这段代码的简单直接移植可能是不可能的。我会很感激这方面的任何帮助。

如果它是相关的,这将用于程序中非常重要的数字运算部分,其中性能很重要。

编辑: fenv.h 中名为 FE_UNDERFLOW 的标志似乎在根据 http://en.cppreference.com/w/cpp/numeric/fenv/FE_exceptions 生成非规范结果时被引发,但已经看到其他几个来源指出,它仅在结果太小时引发,即使对于不正常。将运行测试以查看它是否也满足我的需求,如果是,请自行回答。

【问题讨论】:

这有帮助吗? ***.com/questions/16849009/… 【参考方案1】:

C++11 适合您吗?如果是这样,也许您可​​以在结果上调用std::isnormal,例如http://en.cppreference.com/w/cpp/numeric/math/isnormal.

【讨论】:

看起来即使你没有 C++11 也可以从 Boost 获得它:boost.org/doc/libs/1_41_0/libs/math/doc/sf_and_dist/html/… 对不起,这个代码库现在还需要为 C++03 编译。此外,此操作似乎可以检测矩阵乘法是否产生了任何非正规结果。遍历整个结果矩阵以查看是否有任何值是非正规的,这将是我唯一的选择,而且很可能太慢了,因为这首先是一种速度优化。【参考方案2】:

正如问题中所说,似乎 fenv.h 有一个标志 FE_UNDERFLOW ,在某些架构上至少表明一个低于正常/非正常的结果。我自己的测试表明,在我的测试 x86 架构上似乎就是这种情况,所以除非提供更好的解决方案,否则我将继续使用它。

【讨论】:

以上是关于在 Linux for x86 上检测异常浮点操作的主要内容,如果未能解决你的问题,请参考以下文章

x86 汇编器:浮点比较

x86下 linux qt检测U盘插拔------- HAL 与UDISKS

x86和x64之间的浮点算术的差异

如何在 Linux 上执行适用于 x86、arm、GCC 和 icc 的原子操作?

C++;浮点异常;没有 ./ 运算符

深入理解Linux内核---中断和异常(x86平台)