8

/fp:fast我正在用 C++ 编写实时数字软件,目前正在使用 Visual-C++ 2008 进行编译。现在使用“快速”浮点模型(

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

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

(请参阅:Microsoft Visual C++ 浮点优化

切换到/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 而不是两个 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 
4

5 回答 5

3

添加

#pragma float_control( precise, on)

在计算之前和

#pragma float_control( precise,off)

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

于 2010-08-04T16:39:09.963 回答
2

该文档指出,您可以使用 pragma 逐行控制浮点优化。

于 2010-08-04T16:16:38.863 回答
1

还有__assume。您可以使用 __assume(a/b != (a*(1/b)))。我从未真正使用过 __assume,但理论上它的存在正是为了微调优化器。

于 2010-08-08T15:15:19.803 回答
0

你能把包含这些计算的函数放在一个单独的源代码文件中,并只用不同的设置编译那个文件吗?

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

于 2010-08-04T16:17:37.527 回答
0

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

    a/b; c/b 

->

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

还可以将您从偶尔的 div 中拯救为零

于 2010-08-08T15:03:48.417 回答