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

时间:2010-08-04 16:10:24

标签: 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,版本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 

5 个答案:

答案 0 :(得分:3)

添加

#pragma float_control( precise, on)

计算之前

#pragma float_control( precise,off)

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

答案 1 :(得分:2)

该文档声明您可以使用编译指示逐行控制浮点指向优化。

答案 2 :(得分:1)

还有__assume。你可以使用__assume(a / b!=(a *(1 / b)))。我从来没有真正使用过__assume,但从理论上讲它完全适用于优化优化器。

答案 3 :(得分:0)

您是否可以将包含这些计算的函数放在单独的源代码文件中,并仅使用不同的设置编译该文件?

我不知道这是否安全,你需要检查!

答案 4 :(得分:0)

我发现的(奇怪的)解决方案:每当在函数中除以相同的值时 - 添加一些epsilon:

    a/b; c/b 

- >

    a/(b+esp1); c/(b+esp2)

还可以将您从偶尔的div中删除