6

Is it possible to selectively turn -ffast-math on/off during runtime? For example, creating classes FastMath and AccurateMath with the common base class Math, so that one would be able to use both implementations during runtime? Ditto for flashing subnormals to zero, etc.

In particular, I don't know whether compiling with -ffast-math would emit an instruction that would, once executed, affect all numerical computations in the thread (for example, setting a flag to flush subnormals to zero).

einpoklum
  • 118,144
  • 57
  • 340
  • 684
Michael
  • 5,775
  • 2
  • 34
  • 53
  • 13
    You would need to compile two versions, one with the optimization and one without. Then link them and choose which to invoke at run-time. – Mysticial Aug 12 '13 at 22:00
  • 2
    It is unfortunate that http://stackoverflow.com/questions/7420665/what-does-gccs-ffast-math-actually-do only provides one example, but `-ffast-math`'s effect are mostly (entirely?) compile-time choices, such as compiling `/10` as `*0.1`, or “simplifying” `a+b-a-b` into `0` (it is not zero for IEEE 754 computations). Therefore, as Mysticial says, there is no way to turn the flag on and off at run-time: you must compile two versions if that's what you really want. – Pascal Cuoq Aug 12 '13 at 22:15
  • 1
    @Mysticial make your comment into an answer - it's the only waaay... –  Aug 13 '13 at 12:37
  • 1
    @PascalCuoq. -ffast-math may also enable some instructions that do approximate maths, where CPUs have them (so you get a less accurate square root, say, but you probably don't care). Otherwise I think what you say is accurate. – ams Aug 22 '13 at 16:05
  • What happens if two different source files are compiled with different -ffast-math options? Couldn't that get what the Op wants, as long as all the math operations to be impacted are encapsulated in those two source files? – ash Sep 04 '13 at 19:32

2 Answers2

7

If you don't want to muck with the build system, you can do the following:

#pragma fast-math push
#pragma fast-math on
[..]
#pragma fast-math pop

GCC may have a slightly different syntax, but I would expect it's possible too.

TTimo
  • 1,276
  • 1
  • 13
  • 20
  • 2
    Just to save others googling; the MS compiler has such a pragma as well: https://learn.microsoft.com/en-us/cpp/preprocessor/float-control?view=vs-2019 – AlexGeorg Dec 05 '19 at 12:21
3

Try this:

gcc -ffast-math -c first.c
gcc -c second.c
gcc -o dyn_fast_math first.o second.o

Putting uniquely-named functions in first.c and second.c. This should do the trick. There is rarely any "global" impact of a compiler optimization. If one does exist, linking will likely fail due to the conflict.

I tried a small sample without problem.

Here's an example.

first.c

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;
}

compilation

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

Check the difference between first.s and second.s and you'll find this:

movapd  %xmm1, %xmm2
divsd   %xmm0, %xmm2
movapd  %xmm2, %xmm0

changes to this:

mulsd   %xmm1, %xmm0

Both functions are called, and both return the expected result.

ash
  • 4,867
  • 1
  • 23
  • 33
  • 1
    Thanks. I wonder though whether something like this is doable without changing the build system, which in my case includes dozens on makefile-style scripts for thousands of source files. Is there a #pragma fast-math? Googling for it leads to a bug report that claims that such pragma should work in GCC, but doesn't. – Michael Sep 05 '13 at 14:13
  • Ah, I do not know about a pragma or other means. Make supports modifications to settings for specific targets, if that helps. – ash Sep 05 '13 at 15:38