アイテムの差の二乗和を計算したいとします。
$\sum_{i=1}^{N-1} (x_i - x_{i+1})^2$
最も単純なコード (入力は std::vector<double> xs
、出力はsum2
) は次のとおりです。
double sum2 = 0.;
double prev = xs[0];
for (vector::const_iterator i = xs.begin() + 1;
i != xs.end(); ++i)
{
sum2 += (prev - (*i)) * (prev - (*i)); // only 1 - with compiler optimization
prev = (*i);
}
コンパイラが上記のコメントで最適化を行うことを願っています。N
の長さの場合は、乗算と合計xs
があります(合計はまたはを意味します)。N-1
2N-3
+
-
ここで、次の変数を知っているとします。
$x_1^2 + x_N^2 + 2 \sum_{i=2}^{N-1} x_i^2$
と呼びますsum
。二項平方を展開する:
$sum_i^{N-1} (x_i-x_{i+1})^2 = sum
- 2\sum_{i=1}^{N-1} x_i x_{i+1}$
したがって、コードは次のようになります。
double sum2 = 0.;
double prev = xs[0];
for (vector::const_iterator i = xs.begin() + 1;
i != xs.end(); ++i)
{
sum2 += (*i) * prev;
prev = (*i);
}
sum2 = -sum2 * 2. + sum;
ここでは、N 回の乗算と N-1 回の加算があります。私の場合、N は約 100 です。
さて、g++ -O2
I got no speed up (インライン化された関数を 2M 回呼び出してみる) でコンパイルすると、なぜでしょうか?