c++ - 浮点 C++ 编译器选项 |防止 a/b -> a* (1/b)

标签 c++ visual-c++ optimization floating-point floating-accuracy

我正在用 C++ 编写实时数字软件,目前使用 Visual-C++ 2008 对其进行编译。 现在使用“快速”浮点模型 (/fp:fast),各种优化,其中大部分对我的情况有用,但特别是:

a/b -> a*(1/b) Division by multiplicative inverse

对于我的很多计算来说在数值上太不稳定了。

(参见:Microsoft Visual C++ Floating-Point Optimization)

切换到 /fp:precise 会使我的应用程序运行速度降低两倍以上。是否可以微调优化器(即禁用此特定优化)或以某种方式手动绕过它?

- 实际的最小代码示例:-

void test(float a, float b, float c,
    float &ret0, float &ret1) {
  ret0 = b/a;
  ret1 = c/a;
} 

[我的实际代码主要是矩阵相关算法]

输出:VC (cl, version 15, 0x86) 是:

divss       xmm0,xmm1 
mulss       xmm2,xmm0 
mulss       xmm1,xmm0 

有一个 div 而不是两个在数值上是一个大问题,(xmm0,从 RAM 中预加载 1.0f),因为取决于 xmm1,2 的值(可能在不同的范围内)你可能会损失很多精度(不使用 SSE 编译,输出类似的 stack-x87-FPU 代码)。

包装函数
#pragma float_control( precise, on, push )
...
#pragma float_control(pop)

确实解决了准确性问题,但首先,它仅在函数级别(全局范围)可用,其次,它防止函数内联,(即速度惩罚太高)

“精确”输出也被来回转换为“双倍”:

 divsd       xmm1,xmm2 
 cvtsd2ss    xmm1,xmm1 
 divsd       xmm1,xmm0 
 cvtpd2ps    xmm0,xmm1 

最佳答案

添加

#pragma float_control(precise, on)

计算前

#pragma float_control(precise,off)

之后。我认为应该这样做。

关于c++ - 浮点 C++ 编译器选项 |防止 a/b -> a* (1/b),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3407493/

相关文章:

c++ - 为什么数组形式参数总是隐式转换为指针而不是被禁止?

language-agnostic - 为什么整个程序优化现在不流行了?

mysql - 如何检查MySQL的优化工作与否?

具有内存位置的 C++ 删除运算符

C++传递指针

c++ - 在 Visual Studio for C++ 中分析 dll 加载条件的最佳工具

c - 如何在命令行(Windows)中使用VC++编译器?

c++ - 具有可变参数的嵌套宏在 GCC 中编译但在 MSVC 中不编译

c++ - 间接成本 ~ 浮点乘法的 3 倍,真的吗? (带演示)

c++ - wstring::find() 不适用于非拉丁符号?