2つの円の交点を計算するために次のコードを書いた。コードは単純で十分に速いです。それ以上の最適化は必要ありませんが、このコードをより積極的に最適化することができます。たとえば、h/d
と1.0/d
は2回計算されます(コンパイラの最適化を忘れてみましょう)。コンパイラの最適化をどれだけ信頼できるか?
const std::array<point,2> intersect(const circle& a,
const circle& b) {
std::array<point,2> intersect_points;
const float d2 = squared_distance(a.center, b.center);
const float d = std::sqrt(d2);
const float r12 = std::pow(a.radious, 2);
const float r22 = std::pow(b.radious, 2);
const float l = (r12 - r22 + d2)/(2*d);
const float h = std::sqrt(r12 - std::pow(l,2));
const float termx1 = (1.0/d) * (b.center.x - a.center.x) + a.center.x;
const float termx2 = (h/d)*(b.center.y - a.center.y);
const float termy1 = (1.0/d) * (b.center.y - a.center.y) + a.center.y;
const float termy2 = (h/d)*(b.center.x - a.center.x);
intersect_points[0].x = termx1 + termx2;
intersect_points[0].y = termy1 - termy2;
intersect_points[1].x = termx1 - termx2;
intersect_points[1].y = termy1 + termy2;
return intersect_points;
}
私の質問は、コードを理解して最終的なバイナリを最適化するために、C++コンパイラ(g ++)をどの程度信頼できるかです。 g ++は1.0/d
を2回行うことを避けることができますか?より正確には、どこに行があるかを知りたい。コンパイラーに細かいチューニングを任せて、いつ最適化を行うのですか?
標準ではほとんど最適化については言及していません。コンパイラと提供するフラグによって異なります。 https://godbolt.org/を使用して、特定のコンパイラが出力するものを確認することができます。 –
私は、 'std :: pow(x、2)'を 'x * x'に最適化するコンパイラに頼らないでください。この変更により大幅な改善が得られる可能性があります。 –
* trust *が行く限り、私はそれがそうでないという証拠が出るまで私のコンパイラが正しい結果を生成することを信頼します。出力が予期せぬものであれば、私はすぐにそれが人間のエラーであると仮定します。コンパイラのバグではありません。 –