重复相同计算的优化

时间:2014-07-22 15:51:04

标签: c++ c++11 optimization matrix

考虑以下两个功能:

std::pair<double,Vector> myMatrixOperation1(Matrix const& A, Vector const& V) {
    Vector AV = A*V;
    double norm_A_V = std::sqrt(dot(V,AV));

    return make_pair(norm_A_V,AV);
}

std::pair<double,Vector> myMatrixOperation2(Matrix const& A, Vector const& V) {
    return make_pair( norm(V,A) , A*V );
}
double norm(Vector const& V, Matrix const& innerProductMatrix) {
    double norm_A_V = std::sqrt(dot(V,innerProductMatrix*V));
}

他们显然做了同样的事情,除了Matrix-Vector产品保证在第一个函数中只计算一次。

然而,第二个函数更具可读性,因为为了完全分离关注点而对其进行了重构:关于任意内积的向量范数的概念被抽象为一个单独的函数。

现在的问题是,如果没有任何优化,Matrix-Vector产品现在会被计算两次。

我的问题如下:编译器智能是否只计算一次Matrix-Vector产品?如果是的话,我需要做什么?

我想至少我需要内联norm()函数。 另外,关于operator *(Matrix const&amp; A,Vector const&amp; V),是否有任何帮助的懒惰评价? (旁注:我使用的是特征库)

注意:我知道类似的问题:Will the compiler optimize repeated math computations?。但请注意,我的问题对于编译器来说更难,因为operator *(Matrix const&amp; A,Vector const&amp; V)不是内置的,因此编译器应该需要一些保证

修改

在进一步考虑维基百科(http://en.wikipedia.org/wiki/Optimizing_compiler)的引用之后:

  

例如,在某些语言中,不允许使用函数   副作用。因此,如果程序对同一个程序进行多次调用   函数具有相同的参数,编译器可以立即推断   函数的结果只需要计算一次。在语言中   在允许功能产生副作用的地方,另一种策略是   可能。优化器可以确定哪个函数没有边   效果,并限制这种优化免费副作用   功能。此优化仅在优化程序具有时才可用   访问被调用函数。

似乎编译器可以用第一个提供的操作符+纯粹替换第二个函数(即:没有副作用)。根据{{​​3}},在C ++中,通过告诉编译器函数是constexpr,只有constexpr函数调用,并且有const参数,可以保证编译器的纯度。所以我认为只要满足一些要求,编译器就有可能保证这样的优化。此外,请注意,在C ++ 14中,对constexpr函数的限制已经大大减少了

1 个答案:

答案 0 :(得分:0)

如果速度优化在此代码中很重要,我根本不会依赖编译器行为。

即使一个聪明的编译器发现了这个技巧(我在这里怀疑,因为这会涉及相当多的语义洞察力 - 使内联函数可能暗示编译器),你无法保证其他编译器会看到它。即使是同样的未来版本!

经常出现这种数值算法依赖于中间结果的重用。如果您明确表示您保留结果以供日后使用,我认为没有可读性问题。代码紧凑性并不总是意味着代码可读性。