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

时间:2011-02-08 15:26:44

标签: 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;
};
  

无论数据在何处   存储,臃肿的关键结果   观点是,现在很多 - 也许   所有 - SquareMatrix的成员   函数可以是简单的内联调用   到共享的基类版本   与所有其他矩阵持有   相同类型的数据,无论他们是谁   尺寸。与此同时,SquareMatrix   不同大小的物体是   不同的类型,所以尽管如此,   SquareMatrix&lt; double,5&gt;和   SquareMatrix&lt; double,10&gt;对象使用   同一个成员的职能   SquareMatrixBase&lt; double&gt;,没有   通过的机会   SquareMatrix&lt; double,5&gt;反对a   功能期待a   SquareMatrix&lt; double,10&gt;。很好,不是吗?

     

很好,是的,但不是免费的。版本   用矩阵大小反转   硬连线进入他们很可能   生成比共享更好的代码   大小作为传递的版本   函数参数或存储在   宾语。例如,在   尺寸特定版本,尺寸   因此,它将是编译时常量   有资格获得此类优化   不断传播,包括他们的   被折叠成生成的   指令作为即时操作数。   这不可能在   尺寸无关的版本。

在上一段的上述描述中,它被提及为“因此有资格作为不断传播的优化,包括将它们折叠成 生成的指令作为立即操作数“。这个声明是什么意思?请请解释这个。

谢谢!

2 个答案:

答案 0 :(得分:8)

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

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

编译器会通过传播常量来减少这一点:

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

该计划因此相当于:

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

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

答案 1 :(得分:0)

如果你有原始代码,如:

a:=3;
b:=4;
b+=1;
b+=2;
a:=a+b;

然后编译器可以将语句优化为:

b==7;
a==10;

这称为恒定传播和恒定折叠。