【发布时间】:2014-11-26 04:33:19
【问题描述】:
我在一个平台上工作,当将浮点数与零进行比较时,它会出现严重的停顿。作为优化,我看到使用了以下代码:
inline bool GreaterThanZero( float value )
{
const int value_as_int = *(int*)&value;
return ( value_as_int > 0 );
}
查看生成的程序集,停顿消失了,功能更高效。
这行得通吗?我很困惑,因为 IEEE 技巧的所有优化都使用了 SIGNMASKS 和大量的 AND/OR 操作(例如https://www.lomont.org/papers/2005/CompareFloat.pdf)。强制转换为带符号的 int 有帮助吗?在简单的线束中进行测试不会发现任何问题。
任何见解都会很好。
【问题讨论】:
-
基本上,诀窍是检查高位。二进制补码表示中的非负整数的高位为 0,负整数为 1。很大程度上是巧合,同一位也用作 IEEE 浮点表示中的符号位。
-
它可以工作,但编译器真的不会为像
f > 0这样简单的事情做最佳的事情吗? -
@Barry 如果平台在比较 0f 时出现严重的停顿,那听起来不像我所知道的任何消费者平台。对我来说,这听起来像是一种特殊的硬件。
-
@Barry 这不是过早的优化;有了这个改变,代码运行得更快了,而且编译器不够聪明。我希望是的。比起修复由于与零比较而运行缓慢的 3D 重叠测试,我有更好的事情要担心!
-
@MarkRansom:他们不是。如果至少一个参数是 NaN,
<、<=、>、>=和==总是返回 false。 (实际上,再想十秒钟,他也没有实现比较!(x <= 0)。对于有限的x是x > 0,对于某些NaN 是正确的,但对于其他NaN 不是。
标签: c++ optimization floating-point compare ieee