Constants and compiler optimization in C ++

I read all the tips for const-correctness in C ++ and that this is important (in part) because it helps the compiler optimize your code. What I have never seen is a good explanation of how the compiler uses this information to optimize the code, even good books do not explain what happens behind the curtains.

For example, how the compiler optimizes a method that declares const vs, which is not, but should be. What happens when you enter mutable variables? Do they affect these optimizations of the const methods?

+48
c ++ optimization compiler-construction
Oct 17 '08 at 13:56
source share
12 answers

Let methods be ignored and look only at const objects; the compiler has much more room for optimization here. If the object is declared as const, then (ISO / IEC 14882: 2003 7.1.5.1 (4)):

Except that any member of the class is declared mutable (7.1.1) can be changed, any attempt to change the const object during its lifetime (3.8) leads to undefined.

Allows you to ignore objects that may have mutable members - the compiler can assume that the object will not be changed, so it can make significant optimizations. These optimizations may include things like:

  • inclusion of the value of the object directly in the codes of operations with machines
  • completely eliminating code that can never be achieved, since the const object is used in the conditional expression that is known at compile time.
  • loop unfolding if the const object controls the number of iterations of the loop

Please note that this material only applies if the actual object is const - it does not apply to objects that are accessed through pointers or references to constants, since these access paths can lead to objects that are not constants (they even objects are clearly defined for changing, although const pointers / links, as long as the actual object is not a constant, and you discard the path constant of access to the object).

In practice, I do not think that there are compilers that perform any significant optimization for all types of const objects. but for objects that are primitive types (ints, chars, etc.), I think that compilers can be quite aggressive in optimizing the use of these elements.

+35
Oct 17 '08 at 15:41
source share

I think that the const keyword was mainly introduced to verify compilation of the semantics of the program, and not for optimization.

Herb Sutter, in a GotW # 81 article , explains very well why the compiler cannot optimize anything when passing parameters by const link, or when declaring a const value. The reason is that the compiler has no way to make sure that the reference to the object will not be changed even if const is declared: you can use const_cast, or some other code may have a non-constant reference to the same object.

However, citing Herb Sutter's article:

There is [only] one case where it says "const" can really mean something, and that is, when objects are created by const at the point at which they are defined. In this case, the compiler can often successfully put such โ€œreally comp,โ€ objects into read-only memory [...].

This article has a lot more, so I recommend you read it: after that, you can better understand continuous optimization.

+54
Oct 17 '08 at 2:30 p.m.
source share

manual work begins

In fact, the earlier the data is fixed, the more the compiler can move around the actual data destination, ensuring that the pipeline does not stop

end of record

+6
Oct 17 '08 at 14:03
source share

Fur. Const-correctness is more a style / error check than an optimization. A full-fledged optimizing compiler will follow the use of variables and can determine when a variable is effectively const or not.

Added to this, the compiler cannot rely on the fact that you are telling the truth - you can discard const inside a library function that it does not know about.

So yes, const-correctness is a worthy goal, but it doesnโ€™t tell the compiler anything that it canโ€™t figure out for itself, assuming a good optimizing compiler.

+5
Oct 17 '08 at 14:14
source share

It does not optimize a function declared as const.

It can optimize functions that call a function declared as const.

void someType::somefunc(); void MyFunc() { someType A(4); // Fling(A.m_val); A.someFunc(); Flong(A.m_val); } 

Here, to call Fling valud A.m_val must be loaded into the CPU register. If someFunc () is not const, the value must be reloaded before calling Flong (). If someFunc is const, then we can call Flong with a value that is still in the register.

+3
Oct 17 '08 at 14:11
source share

The main reason for having methods like const is for constant correctness, and not for possible optimization of compilation of the method itself.

If variables are constants, they can (theoretically) be optimized. But only the compiler sees the scope. After the compiler must allow them to be changed using const_cast elsewhere.

+3
Oct 17 '08 at 14:13
source share

These are all correct answers, but the answers and the question seem to suggest one thing: compiler optimization really matters.

There is only one type of code in which compiler optimization is important, i.e. in code

  • tight inner loop
  • in the code you compile, unlike a third-party library,
  • does not contain calls to functions or methods (even hidden ones),
  • where the program counter spends a noticeable part of its time

If the remaining 99% of the code is optimized to the Nth degree, this will not make a difference in the difference, because it matters only in the code, where the program counter actually spends time (which you can find from the sample).

+2
Dec 23 '08 at 20:23
source share

I would be surprised if the optimizer actually put a lot of stock into the const declaration. There is a lot of code that ultimately robs const-ness, it would be a very reckless optimizer that would rely on the expression of a programmer to suggest when the state might change.

+1
Oct 17 '08 at 14:15
source share

const-correctness is also useful in documentation. If a function or parameter is specified as const, I donโ€™t need to worry about the value changing from under my code (unless someone else on the team is very mischievous). I'm not sure if this would really be worth it if it were not integrated into the library.

+1
Dec 23 '08 at 21:25
source share

The most obvious point where const is direct optimization is passing arguments to a function. It is often important to ensure that the function does not modify the data, so the only real choices for the function signature are as follows:

 void f(Type dont_modify); // or void f(Type const& dont_modify); 

Of course, the real magic here passes the link, rather than creating a (expensive) copy of the object. But if the link was not marked as const , this will weaken the semantics of this function and will have negative effects (for example, more complex error tracking). Therefore const allows us to optimize here.

/ EDIT: in fact, a good compiler can analyze the control flow of a function, determine that it does not change the argument and does not optimize (by passing a link, not a copy). const here is just help for the compiler. However, since C ++ has rather complicated semantics, and such control flow analysis can be very expensive for large functions, we probably should not rely on compilers for this. Does anyone have data to support me / prove that I'm wrong?

/ EDIT2: and yes, as soon as custom copy constructors come into play, it becomes even more complicated, because compilers, unfortunately, are not allowed to skip them in this situation.

0
Oct 17 '08 at 14:58
source share

This code,

 class Test { public: Test (int value) : m_value (value) { } void SetValue (int value) const { const_cast <Test&>(*this).MySetValue (value); } int Value () const { return m_value; } private: void MySetValue (int value) { m_value = value; } int m_value; }; void modify (const Test &test, int value) { test.SetValue (value); } void main () { const Test test (100); cout << test.Value () << endl; modify (test, 50); cout << test.Value () << endl; } 

outputs:

 100 50 

which means that the declared const object has been changed in the const member function. The presence of const_cast (and the mutable keyword) in C ++ means that the const keyword cannot help the compiler to create optimized code. And, as I pointed out in my previous posts, this can even lead to unexpected results.

Usually:

const! = optimization

In fact, this is a legitimate C ++ modifier:

 volatile const 
0
Oct 17 '08 at 15:17
source share

const helps compilers optimize mainly because it allows you to write optimizable code. If you do not enter const_cast .

-one
Oct 17 '08 at 18:51
source share



All Articles