天天看点

C++性能优化笔记-6-C++元素的效率差异-17-栈展开、NAN和INF传播栈回滚的其他情形NAN和INF的传播

C++元素的效率差异

  • 栈回滚的其他情形
  • NAN和INF的传播

栈回滚的其他情形

前面的章节描述了由异常处理使用的、称为栈回滚的机制,在异常出现时,不使用正常返回途径跳出函数后,由异常处理用来清理及调用所有必须的析构函数。这个机制也用在其他两个情形里:

  • 在线程终止时,可以使用栈回滚机制。目的是检测线程中声明的对象是否有需要调用的析构函数。建议在终止线程前,从要求清理的函数返回。不能确定的,

    _endthread()

    的调用会清理栈。取决于实现。
  • 在使用函数

    longjmp

    跳出一个函数时,也使用栈回滚机制。尽可能避免使用

    longjmp

    。在时间因是关键因素的代码中,不要依赖

    longjmp

NAN和INF的传播

在大多数情形中,浮点错误会传播到一系列计算的结果中。对于异常和错误陷阱,这是一个非常高效的可选方案。浮点溢出和除以 0 会产生无穷。加上或乘以无穷仍然是无穷。

INF

可能以这种方式传播到最终结果。然而,不是所有和

INF

有关的操作都会产生

INF

的结果。特殊的例子,

INF - INF

INF / INF

会产生

NAN

(not-a-number)。

0 / 0

,一个函数的输入超出范围(例如,

sqrt(-1), log(-1)

)也会产生

NAN

。大多数以

NAN

为输入的操作也会产生

NAN

的结果,所以

NAN

也会传播到最终结果。这是一个检测浮点错误的高效的方法。几乎所有的浮点错误都会传播道最终结果,以

INF

NAN

表现。

INF

NAN

的传播没有额外的代价,也不需要额外的代码来追踪。

一个

NAN

可以作为一些额外的信息的负载。一个函数库可以把错误码放进这个负载来处理处理错误,这个负载也会传播到最终结果。函数

finite()

,当参数是

NAN

INF

时会返回

false

,当参数是正常浮点数时返回

true

。这可以用作检测错误,例如在浮点数转成整数之前。

INF

NAN

传播的细节可以参考nan_propagation中的"NAN propagation versus fault trapping in floating point code" 。其中也讨论了

INF

NAN

传播失败的情况,还有编译器对

INF

NAN

传播的相关优化选项。

继续阅读