【问题标题】:What does the compiler optimization "constant propagation" mean?编译器优化“不断传播”是什么意思?
【发布时间】:2011-02-08 15:26:43
【问题描述】:

来自 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 对象使用 相同的成员函数 SquareMatrixBase,没有 通过的机会 SquareMatrix 对象 函数期望一个 方阵。不错,不是吗?

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

在上一段的上述描述中,它被提及为“因此有资格进行诸如常量传播之类的优化,包括将它们折叠到 生成指令作为立即操作数”。这句话是什么意思?请解释一下。

谢谢!

【问题讨论】:

标签: c++ templates code-size


【解决方案1】:

常量传播是一种非常简单(原则上)留给编译器的优化。

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

【讨论】:

    【解决方案2】:

    如果您有类似的原始代码:

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

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

    b==7;
    a==10;
    

    这就是所谓的常量传播和常量折叠。

    【讨论】:

      猜你喜欢
      • 2018-06-13
      • 2021-05-17
      • 2015-09-02
      • 2020-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多