ほとんどのデータ型ではテールコールを最適化できるテンプレート化されたコードがいくつかあります。コードはPOW()なぜboost :: multiprecision :: cpp_intを使ってテールコールの最適化に影響を与えるのですか
template<typename T, typename U>
void powRecurse(T& x, U& y, T& acc)
{
if(y == 0) {
acc = Identity<T>;
return;
}
if(y == 1) {
acc = acc * x;
return;
}
if(y % 2 == 1) {
acc = acc * x;
y = y - 1;
}
x = x*x;
y = y/2;
powRecurse<T, U>(x, y, acc);
}
template<typename T, typename U>
T tailPow(T x, U y)
{
T rv = Identity<T>;
powRecurse<T, U>(x, y, rv);
return rv;
}
を実装し、パラメータTの種類は、私が試したいずれかの種類が尾がパラメータ場合は、パラメータU.のための右の種類を最適化呼び出すことができ、何の末尾呼び出しの最適化に影響を与えていないようですUはuint64_tです。コンパイラはtail呼び出しを最適化できます。 boost :: multiprecision :: cpp_intの場合、コンパイラはtail呼び出しを最適化しません。
また、両方のtail呼び出しを最適化するint型のクラスとテンプレートラッパーでuint64_tをラップしようとしました。
テールコールが最適化されない理由はありますか?明らかにこれをループすることができますが、ここでは言語やコンパイラの問題を理解しようとしています。
明白な、おそらく役に立たないコメント:コンパイラが最適化には義務を持っていないと、彼らは、私の知る限りでの集まりですヒューリスティックなので、 'cpp_int'が"十分に大きい "場合、コンパイラは末尾の再帰がそれに値するものではないと考えるかもしれません。それは非常に興味深いのですが、gcc(または他のコンパイラの)内部については十分な知識がなければ答えられるとは思えません。 – yeputons
@yeputonsありがとう、ほとんど私はそれを不可能にする何かcpp_intにないと確信していません。一方、テールコールの最適化が悪化するケースは想像できませんが、インライン化後の関数の長さと最適化の可能性を識別できないアナライザが問題であることは想像できます。 –