简体   繁体   English

GCC是否会为运行时保留固定值的算术或编译输出?

[英]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. 我想知道GCC是否会将算术与固定值保持在运行时执行,或者它是否会将其设置为它的答案,例如。

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? 或者算术运行时间?

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. 即使是冗长的计算也可以在编译时完成......这实际上是模板非类型参数评估和(现在) constexpr变量所必需的。

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: 要理解为什么,假设float最多有5位精度:

   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). 例如, 对于gcc ,这可能由-freciprocal-math (真的不知道)控制。 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. 您需要为您使用的每个选项组合检查此输出。

Today is your lucky day, because you find out about Agner Fog and his amazing in depth c++ manuals ! 今天是你的幸运日,因为你发现了关于Agner Fog及其惊人的深度c++手册 If you look at section 8.2 of this one you will see that basically all compilers are capable of constant folding. 如果你看一下这一节的第8.2节,你会发现基本上所有编译器都能够进行恒定折叠。

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 ). 虽然为了确保在您的编译器选项的特定情况下确实发生了这种情况,但您应该按照上面的建议检查程序集输出(使用-S )。 I like to put something like asm("MY_LABEL:"); 我喜欢把像asm("MY_LABEL:");这样的东西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. 在这种情况下,我不相信它会改变任何东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM