MSVC C++中强制循环展开

问题描述

想象以下代码:

for (int i = 0; i < 8; ++i) {
    // ... some code
}

我希望在 MSVC 中展开此循环。在 CLang 中,我可以在循环之前添加 #pragma unroll。但是如何在 MSVC 中做同样的事情?

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

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

Try it online!

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; });
}

但是是否有可能在没有像上面这样更困难的代码的情况下在 MSVC 中强制展开?

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

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

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

解决方法

你不能直接。最接近的 #pragma#pragma loop(...),它没有展开选项。这里的重点是配置文件引导优化 - 配置您的程序,MSVC 将知道此循环运行的频率。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...