Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Loop unrolling

28 views
Skip to first unread message

Alvin

unread,
Mar 5, 2017, 8:09:50 AM3/5/17
to
I'm wondering if there is a more elegant way to write the following code
in C++14. The purpose is to duplicate a set of statements (fully unroll
a loop). The loop index isn't required.


#include <iostream>
#include <utility>

using expand = size_t[];

template<typename fn_t, size_t... seq>
void unroll_helper(const fn_t& fn, std::index_sequence<seq...>) {
expand{ (fn(), seq)... };
}

template<size_t cnt, typename fn_t>
void unroll(const fn_t& fn) {
unroll_helper(fn, std::make_index_sequence<cnt>());
}

int main() {
unroll<4>([]() { std::cout << "Hello world.\n"; });
}

Dombo

unread,
Mar 5, 2017, 8:46:04 AM3/5/17
to
Op 05-Mar-17 om 14:09 schreef Alvin:
I'm wonder why you don't just use a for loop? If loop unrolling makes
sense then chances are the optimizer will do that for you. If it doesn't
make sense (like the example above where streaming to std::cout will
make the loop overhead negligible) why would you want to unroll it any way?


Alvin

unread,
Mar 5, 2017, 8:57:52 AM3/5/17
to
On 2017-03-05 14:48, Dombo wrote:
>
> I'm wonder why you don't just use a for loop? If loop unrolling makes
> sense then chances are the optimizer will do that for you. If it doesn't
> make sense (like the example above where streaming to std::cout will
> make the loop overhead negligible) why would you want to unroll it any way?

The real usage is a bunch of timing-sensitive inline assembly. A loop
won't do it.

Dombo

unread,
Mar 5, 2017, 9:27:37 AM3/5/17
to
Op 05-Mar-17 om 14:57 schreef Alvin:
In that case you might want to make sure that the inline assembly does
not upset the optimizer too much (i.e. check the assembly output to see
if produces what you want to). For example on Visual Studio (since you
are talking about timing sensitive I'm pretty sure that is NOT what you
are using) inline assembly effectively disables the optimizer for that part.

To get back to your question; an alternative way unroll would be to use
partial template specialization:


template<size_t count>
struct unroll : unroll<count - 1>
{
template<typename F>
unroll(F& f) : unroll<count - 1>(f)
{
f();
}
};

template<>
struct unroll<0>
{
template<typename F>
unroll(F& f)
{
}
};

Wouter van Ooijen

unread,
Mar 5, 2017, 12:08:51 PM3/5/17
to
Op 05-Mar-17 om 14:09 schreef Alvin:
> I'm wondering if there is a more elegant way to write the following code
> in C++14. The purpose is to duplicate a set of statements (fully unroll
> a loop). The loop index isn't required.

This seemed to work for me (at least with the higher optimization settings):

template< int N >
struct loop_unrolled{
template< typename Body >
loop_unrolled( const Body & body ){
body();
loop_unrolled< N - 1 > dummy( body );
}
};

template<>
struct loop_unrolled< 0 >{
template< typename Body >
loop_unrolled( const Body & body ){}
};

int n = 0;
loop_unrolled< 8 >( [&]{
std::cout << static_cast( n++ )<< " ";
});

see http://www.voti.nl/blog/?p=81

Wouter "Objects? No Thanks!" van Ooijen

Manfred

unread,
Mar 5, 2017, 3:38:43 PM3/5/17
to
You know that you can do this all in assembly, like using %rep in nasm
and REPEAT in masm, right? Not sure if they are supported by your
compiler, though.
0 new messages