循环展开和元编程(TMP)

loop unrolling and metaprogramming(TMP)?

本文关键字:TMP 编程 循环展开      更新时间:2023-10-16

读取 [编译时代码优化]

template <int length>
Vector<length>& Vector<length>::operator+=(const Vector<length>& rhs) 
{
    for (int i = 0; i < length; ++i)
        value[i] += rhs.value[i];
    return *this;
}

编译器实例化上述函数模板时,可能会产生以下代码:[需要引用]

template <>
Vector<2>& Vector<2>::operator+=(const Vector<2>& rhs) 
{
    value[0] += rhs.value[0];
    value[1] += rhs.value[1];
    return *this;
}

编译器的优化器应能够展开for循环,因为模板参数长度在编译时是常数。

但是,请谨慎行事,因为这可能会导致代码膨胀,因为将对您实例化的每个" n"(向量大小)生成单独的展开代码。

但是,我在编写TMP代码时学会了,应该避免循环,因为它是运行时,并且使用模板递归是一个变化。

我已经在Google上进行了搜索编辑,并找到了该问题,该问题是手动的。答案还鼓励使用递归。

因此,我应该依靠编译时代码优化,能够使用编译时长度(循环的结尾)在编译时间或始终使用递归?

>

我认为Wikepedia的文章鼓励我们依靠Un-Roll。也许我误会了?

循环展开与模板无关(至少一般而言)。当已知尺寸时,编译器可以展开循环(它们也可能能够展开静态界限的循环,但这要困难得多)。

如果您使用模板递归,这仅意味着您可以控制循环展开的方式。

无论如何,不要尝试进行过早的优化...滚动循环不太可能是您的运行时成本问题。让编译器展开至少是免费的,而独自行动有点痛苦且容易出错,而不确定结果是否值得付出努力。

从我的经验循环展开到一定长度。我猜如果代码生长太大,这对缓存产生负面影响,并且导致少于最佳性能