我正在编写实时数字软件,使用C++编写,目前使用Visual-C++ 2008进行编译。
现在使用“快速”浮点模型(/fp:fast),各种优化,其中大部分对我的情况有用,但具体来说:
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而不是两个在数值上是一个很大的问题,(xmm0从RAM中预加载了1.0f),因为根据xmm1,2的值(可能处于不同的范围内),您可能会失去很多精度(编译时没有SSE,则输出类似的堆栈-x87-FPU代码)。
将函数包装起来
#pragma float_control( precise, on, push )
...
#pragma float_control(pop)
解决了精度问题,但首先,它仅适用于函数级别(全局范围),其次,它会阻止函数的内联(即速度惩罚太高)。
“precise”输出也被反复转换为“double”。
divsd xmm1,xmm2
cvtsd2ss xmm1,xmm1
divsd xmm1,xmm0
cvtpd2ps xmm0,xmm1