我正在用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
答案 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)
a/b; c/b
- >
a/(b+esp1); c/(b+esp2)
还可以将您从偶尔的div中删除