在运行时是否有可能选择性地打开/关闭-ffast-math?例如,创建具有公共基类Math的类FastMath和AccurateMath,以便能够在运行时使用两种实现?对于将次规范化值闪烁为零等操作也是如此。
特别是,我不知道使用-ffast-math编译是否会发出一条指令,一旦执行,就会影响线程中的所有数值计算(例如,设置一个标志来清除次规范化值)。
在运行时是否有可能选择性地打开/关闭-ffast-math?例如,创建具有公共基类Math的类FastMath和AccurateMath,以便能够在运行时使用两种实现?对于将次规范化值闪烁为零等操作也是如此。
特别是,我不知道使用-ffast-math编译是否会发出一条指令,一旦执行,就会影响线程中的所有数值计算(例如,设置一个标志来清除次规范化值)。
#pragma fast-math push
#pragma fast-math on
[..]
#pragma fast-math pop
试试这个:
gcc -ffast-math -c first.c
gcc -c second.c
gcc -o dyn_fast_math first.o second.o
extern double second();
double first ()
{
double dbl;
dbl = 1.0;
dbl /= 10.0;
return dbl;
}
int main ()
{
printf("first = %f\n", first());
printf("second = %f\n", second());
return 0;
}
second.c
double second ()
{
double ddbl;
ddbl = 1.0;
ddbl /= 10.0;
return ddbl;
}
编译
gcc -S first.c
gcc -c first.s
gcc -ffast-math -S second.c
gcc -ffast-math -c second.s
gcc -o prog first.o second.o
检查first.s和second.s之间的差异,你会发现:
movapd %xmm1, %xmm2
divsd %xmm0, %xmm2
movapd %xmm2, %xmm0
将此更改为:
mulsd %xmm1, %xmm0
两个函数都被调用,并且都返回了预期的结果。
-ffast-math
的效果大多数(完全?)是编译时选择,例如将/10
编译为*0.1
,或者将“简化”a+b-a-b
为0
(对于IEEE 754计算而言并非为零)。因此,正如Mysticial所说,没有办法在运行时打开和关闭标志:如果您真的想要这样做,必须编译两个版本。 - Pascal Cuoq