Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the compiler optimization "constant propagation" mean?

From Effective C++ by Scott Meyers:

template<typename T, std::size_t n>
class SquareMatrix: private SquareMatrixBase<T> {

public:

    SquareMatrix( ) 
     : SquareMatrixBase<T>(n, 0), 
       pData(new T[n*n]) 
    {
         this->setDataPtr(pData.get()); 
    } 

        ...
private:

    boost::scoped_array<T> pData;
};

Regardless of where the data is stored, the key result from a bloat point of view is that now many — maybe all — of SquareMatrix’s member functions can be simple inline calls to base class versions that are shared with all other matrices holding the same type of data, regardless of their size. At the same time, SquareMatrix objects of different sizes are distinct types, so even though, e.g., SquareMatrix<double, 5> and SquareMatrix<double, 1 0> objects use the same member functions in SquareMatrixBase<double>, there’s no chance of passing a SquareMatrix<double, 5> object to a function expecting a SquareMatrix<double, 1 0>. Nice, no?

Nice, yes, but not free. The versions of invert with the matrix sizes hardwired into them are likely to generate better code than the shared version where the size is passed as a function parameter or is stored in the object. For example, in the size-specific versions, the sizes would be compile-time constants, hence eligible for such optimizations as constant propagation, including their being folded into the generated instructions as immediate operands. That can’t be done in the size-independent version.

In above description in last paragraph it was mentioned as "hence eligible for such optimizations as constant propagation, including their being folded into the generated instructions as immediate operands". What does this statment mean? Kindly request to explain this.

Thanks!

like image 662
venkysmarty Avatar asked Feb 08 '11 15:02

venkysmarty


1 Answers

Constant Propagation is a very simple (in the principle) optimization left to compilers.

size_t radius = 5;
size_t diameter = 2*radius;
float perimeter = diameter * 3.1416f;

This will be reduce by the compiler by propagating the constants:

  • notice that the value of radius is known
  • execute the computation of 2*radius (this is constant folding)
  • the value of diameter is therefore known
  • execute the computation of diameter * 3.1416f
  • the value of perimeter is therefore known

The program is thus equivalent to:

size_t radius = 5;
size_t diameter = 10;
float perimeter = 31.416f;

Note that there are many other forms of optimization, for example, if radius and diameter are now no longer needed, we could remove them and only keep the perimeter.

like image 99
Matthieu M. Avatar answered Oct 21 '22 13:10

Matthieu M.