2017-02-06 10 views
0

共通の部分式を含むかなり長い式を計算する必要があります。たとえば、以下の2つの式を考える:コンパイラの共通部分式の除去はどれぐらい効果的ですか?

double dfdx1 = 2 * (-x2 + x1 - sin(b2)*n34 + cos(b2)*sin(c2)*n24 - cos(b2)*cos(c2)*n14 + sin(b1)*m34 - cos(b1)*sin(c1)*m24 + cos(b1)*cos(c1)*m14); 

double dfdx2 = -2 * (-x2 + x1 - sin(b2)*n34 + cos(b2)*sin(c2)*n24 - cos(b2)*cos(c2)*n14 + sin(b1)*m34 - cos(b1)*sin(c1)*m24 + cos(b1)*cos(c1)*m14); 

さておき、すべての三角関数を排除するから、1つの明らかな除去はdfdx2 = -dfdx1です。問題は、コンパイラがこれを認識するかどうかです。私は、MATLABのMuPad generate::optimize()関数を使用していないことが分かりました。これはむしろ私を驚かせました。

double f1 = a*a + b*b - c*a - c*b; 
double f2 = c*a + c*b - a*a - b*b; 

それとも単なる用語にa*ab*bc*ac*bを排除します:

は、より一般的には、コンパイラは、以下の例ではf2 = -f1ことを認識するだろうか?

私はMSVCコンパイラを使用していますが、すべて同じことをすると思います。

答えて

3

通常、コンパイラはこれを認識し、「高速数学」(gccの-ffast-math)を有効にすると、尋ねられた変換を実行する必要があります。その理由は、浮動小数点演算は完全に正確ではなく、式の評価の順序が重要であるためです。

例(ダブルスのために、すべての定数は、実際に他の操作の結果であることと考えられている):

"1e100"+"1.0"-"1e100" results in 0.0 

"1e100"-"1e100"+"1.0" results in 1.0 

明示的な変換を許すのであれば、コンパイラは式だけを並べ替えます。

関連する問題