编译器优化"常量传播"是什么意思?

ven*_*rty 5 c++ templates code-size

来自Scott Meyers的Effective C++:

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;
};
Run Code Online (Sandbox Code Playgroud)

无论数据存储在何处,从膨胀的角度来看,关键结果是,现在很多 - 也许全部 - SquareMatrix的成员函数可以是对基类版本的简单内联调用,这些基类版本与所有其他具有相同类型的矩阵共享数据,无论其大小.同时,不同大小的SquareMatrix对象是不同的类型,所以即使例如SquareMatrix <double,5>和SquareMatrix <double,1 0>对象在SquareMatrixBase <double>中使用相同的成员函数,也没有机会将SquareMatrix <double,5>对象传递给期望SquareMatrix <double,1 0>的函数.很好,不是吗?

很好,是的,但不是免费的.具有硬连线的矩阵大小的反转版本可能比共享版本生成更好的代码,其中大小作为函数参数传递或存储在对象中.例如,在特定于大小的版本中,大小将是编译时常量,因此有资格进行常量传播等优化,包括将它们作为立即操作数折叠到生成的指令中.这不能在与大小无关的版本中完成.

在上一段的上述描述中,它被称为"因此有资格进行恒定传播等优化,包括将它们作为立即操作数折叠到生成的指令中".这个陈述是什么意思?请来解释一下.

谢谢!

Mat*_* M. 10

Constant Propagation是一个非常简单(原理上)优化的编译器.

size_t radius = 5;
size_t diameter = 2*radius;
float perimeter = diameter * 3.1416f;
Run Code Online (Sandbox Code Playgroud)

编译器通过传播常量来减少这种情况:

  • 注意到的价值radius是已知的
  • 执行计算2*radius(这是常数折叠)
  • diameter因此,价值是已知的
  • 执行计算 diameter * 3.1416f
  • perimeter因此,价值是已知的

该计划因此相当于:

size_t radius = 5;
size_t diameter = 10;
float perimeter = 31.416f;
Run Code Online (Sandbox Code Playgroud)

请注意,有许多其他形式的优化,例如,如果radiusdiameter现在不再需要,我们可以将其删除,只保留perimeter.