问题描述
我有一些模板代码,编译器可以对大多数数据类型进行尾调用优化,而对其他数据类型则不能.该代码实现了pow()
I have some templated code that compilers can tail call optimize for most data types but not others. The code implements pow()
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,则编译器可以进行尾部调用优化.如果使用boost :: multiprecision :: cpp_int,则编译器不会进行尾部优化.
The type of parameter T seems to have no affect on tail call optimization, any types I've tried can be tail called optimized with the right types for the parameter U. If parameter U is a uint64_t the compiler can tail call optimize. If it's boost::multiprecision::cpp_int then the compiler doesn't tail call optimize.
我也尝试过将uint64_t包装在一个类中,并将模板包装器包装在int类型上,这两种类型都可以优化尾部调用.
I've also tried wrapping a uint64_t in a class and a template wrapper on an int type which both tail call optimize.
请问是否有任何理由不应该优化尾部调用?显然,我可以循环执行此操作,但实际上我只是在尝试了解此处的语言或编译器问题.
Is there any reason this shouldn't tail call optimize? Obviously I could loop this but I'm really just trying to understand the language or compiler issues here.
推荐答案
惰性计算意味着所有递归"函数调用实际上都是不同的函数模板实例化.
Lazy evaluation implies that all the "recursive" function calls are actually different function template instantiations.
例如参见在这里进行类似的讨论:
See e.g. a similar discussion here:
- Boost multiprecision : Recursive template instantiation exceeded maximum length 256
- or here How to use sqrt and ceil with Boost::multiprecision?
因此,您可以通过退出延迟评估模板表达式(如链接中所述的boost::multiprecision::et_off
)来获得期望的所有tail-coll实现细节,但请务必检查减少的代码-尺寸和可感知的TCO优化实际上可提高性能.
So, you can have all the tail-coll implementation details as you expect it by opting out of the lazy-evaluation template expressions (boost::multiprecision::et_off
as described in the links), but be sure to check that the reduced code-size and perceived TCO optimization actually leads to increased performance.
实际上,某些算法受益于可以跳过常见子表达式,对无损操作进行重新排序等的表达式模板.
In reality, certain algorithms benefit from expression templates that can skip common sub expressions, reorder lossless operations etc.
这篇关于为什么在这里使用boost :: multiprecision :: cpp_int会影响尾调用优化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!