在特殊情况下展开循环循环

p c*_*ark 5 c++ gcc loop-unrolling

因此,我正在尝试优化一些代码。我有一个可变大小的循环功能。但是,为了提高效率,我想将具有1、2和3大小的循环的案例设为完全展开的特殊案例。到目前为止,我的方法是将循环大小声明为const参数,然后定义包装函数,这些包装函数调用主函数,将其递归为const值的文字。我已经包含了一段代码片段,说明了我的想法。

inline void someFunction (const int a)
{
    for (int i=0; i<a; i++)
    {
        // do something with i.
    }
}

void specialCase()
{
    someFunction (3);
}

void generalCase(int a)
{
    someFunction (a);
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是期望我的编译器(GCC)在specialCase内部展开for循环是否合理?我的意思是显然我可以复制-将someFunction的内容粘贴到specialCase中,并用3替换a,但是为了清楚起见,我宁愿只在代码中处理someFunction的一个定义。

Vit*_*meo 3

然而,为了提高效率,我想制作具有 1、2 和 3 个大小的循环的特殊情况,这些情况是完全展开的。

您是否测量过这实际上更快?我怀疑它会(或者编译器不会自动展开循环)。


到目前为止,我的方法是将循环大小声明为 const 参数,然后定义调用主函数的包装函数,为其传递 const 值的文字。

const这里没有任何意义。它不会影响编译器展开循环的能力。它只是意味着a不能在函数体内改变,但它仍然是一个运行时参数。


如果你想确保展开,那就强制展开。使用 C++17 非常容易。

template <typename F, std::size_t... Is>
void repeat_unrolled_impl(F&& f, std::index_sequence<Is...>)
{
    (f(std::integral_constant<std::size_t, Is>{}), ...);
}

template <std::size_t Iterations, typename F>
void repeat_unrolled(F&& f)
{
    repeat_unrolled_impl(std::forward<F>(f), 
                         std::make_index_sequence<Iterations>{});
}
Run Code Online (Sandbox Code Playgroud)

Godbolt 上的实例