Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will GCC leave arithmetic with fixed values for run-time or compile the output?

I am wondering if GCC will leave arithmetic with fixed values to be executed at run-time or if it will set it to it's answer, eg.

const float halfPi = M_PI/2;

Will it "boil down" the equation and set

const float halfPi = 1.57079;

Or leave the arithmetic for run-time?

like image 207
Erkling Avatar asked Apr 02 '13 10:04

Erkling


2 Answers

Well... if we were talking about integrals the answer would be a clear-cut yes (under the general term Constant Folding). Even long-winded computations can be done at compile-time... and this is actually required for templates non-type parameters evaluation and (now) constexpr variables.

In the case of floating point representations, things get a bit complicated as soon as computations get a bit more complicated. The issue is that floating point representations of different sizes (and thus precisions) will yield different results for the same base inputs.

To understand why, suppose that float has, at most, 5 digits of precisions:

   5.0000 + 0.00001
-> 5.00001
-> 5.0000 (truncation to 5 digits)

   5.0000 + 0.00001 + ... + 0.00001 (10 times)
-> 5.0000 + 0.00001 + ... + 0.00001 (9 times)
-> 5.0000 + 0.00001 + ... + 0.00001 (8 times)
-> ...
-> 5.0000

Surprising... right ? If the compilation is done at runtime, then the result may vary depending on whether a register (with larger bitwidth) is used or not.

Therefore, whether constant folding occurs probably depends on the set of optimization flags you use. For example, for gcc, this might be controlled by -freciprocal-math (no idea really). Because even though the compiler certainly can do it, you might be telling it not to (unknowingly).

So the only sure way to test this is to check the compiler output; either by inspecting the object code OR by asking the compiler to emit assembly. And you will need to check this output for every combination of options that you use.

like image 146
Matthieu M. Avatar answered Nov 09 '22 17:11

Matthieu M.


Today is your lucky day, because you find out about Agner Fog and his amazing in depth c++ manuals! If you look at section 8.2 of this one you will see that basically all compilers are capable of constant folding.

Although to make sure it does occur in this particular case with your compiler options, you should check the assembly output as suggested above (use -S). I like to put something like asm("MY_LABEL:"); nearby in the code to make it easy to find, but bear in mind that this can change the meaning of the code, and hence how the compiler interprets it. In this case I don't believe it would change anything.

like image 44
BoBTFish Avatar answered Nov 09 '22 18:11

BoBTFish