在 MSVC C++ 中强制展开循环

Art*_*oul 2 c++ clang visual-c++ loop-unrolling clang++

想象一下下面的代码:

for (int i = 0; i < 8; ++i) {
    // ... some code
}
Run Code Online (Sandbox Code Playgroud)

我希望这个循环在 MSVC 中展开。在 CLang 中我可以添加#pragma unrollbefore 循环。但是在 MSVC 中如何做同样的事情呢?

我知道无论如何编译器通常会为我展开这个循环,即使没有任何编译指示。但我想真正确定这一点,我想总是展开它。

当然,强制展开的一种方法是使用传入函子的模板化展开函数的递归调用,如以下代码所示:

在线尝试一下!

template <int N, int I = 0, typename F>
inline void Unroll(F const & f) {
    if constexpr(I < N) {
        f.template operator() <I> ();
        Unroll<N, I + 1>(f);
    }
}

void f_maybe_not_unrolled() {
    int volatile x = 0;
    for (int i = 0; i < 8; ++i)
        x = x + i;
}

void f_forced_unrolled() {
    int volatile x = 0;
    Unroll<8>([&]<int I>{ x = x + I; });
}
Run Code Online (Sandbox Code Playgroud)

但是,如果没有像上面这样更困难的代码,是否可以在 MSVC 中强制展开?

CLang 是否有可能真正强制展开,我想这#pragma unroll只是给 CLang 一个提示(或者我不对),也许有类似的东西#pragma force_unroll,是吗?

另外,我只想展开这个单个循环,我不需要像传递命令行参数来强制展开所有可能的循环这样的解决方案。

注意:对我来说,在所有 100% 情况下强制展开代码并不重要。我只是需要它在大多数情况下发生。基本上我只是想找出 MSVC 与 CLang 相同的情况,#pragma unroll平均而言,与不使用编译指示相比,编译器更有可能展开循环。

MSa*_*ers 5

你不能直接。最接近的#pragma#pragma loop(...),并且没有展开选项。这里的大锤是配置文件引导优化——配置你的程序,MSVC 将知道这个循环运行的频率。