Search code examples
c++visual-c++clangclang++loop-unrolling

Forcing loop unrolling in MSVC C++


Imagine following code:

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

I want this loop to be unrolled in MSVC. In CLang I can add #pragma unroll before loop. But how to do same in MSVC?

I understand that anyway compilers often will unroll this loop for me even without any pragmas. But I want to be really sure about this, I want to unroll it always.

Of cause one way to force unrolling is to use recursive call of templated unrolling function with passed-in functor, like in following code:

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

But is it possible to force unroll in MSVC without such more difficult code like above?

Also is it possible for CLang to really force unrolling, I'm thinking that #pragma unroll just gives a hint to CLang (or I'm not right), maybe there is something like #pragma force_unroll, is there?

Also I want to unroll just this single loop, I don't need solution like passing command line arguments to force unrolling ALL possible loops.

Note: For me is not really crucial for code to be really forced unrolled in all 100% cases. I just need it to happen in most cases. Basically I just want to find out for MSVC same like CLang's #pragma unroll which on average make compiler more likely to unroll loop than without using pragma.


Solution

  • You can't directly. The closest #pragma is #pragma loop(...), and that doesn't have an unroll option. The big hammer here is Profile Guided Optimization - profile your program, and MSVC will know how often this loop runs.