Categories
Blog Code

Unrolling loops with templates

// Call the passed function object N times. This 'unrolls' the loop
// explicitly in assembly code, rather than creating a runtime loop.
template <unsigned int N, typename Fn>
void unroll(Fn&& fn) {
    if constexpr (N != 0) {
        unroll<N - 1>(fn);
        fn(N - 1);
    }
}

// extern function ensures the loop is not optimised away
extern void somethin(unsigned int i);

// Call somethin 4 times, passing the count each time
void four_somethins() {
    unroll<4>([](unsigned int i) {
        somethin(i);
    });
}

Compiling on https://godbolt.org/ with flags -std=c++17 -O3 gives

four_somethins():                    # @four_somethins()
        push    rax
        xor     edi, edi
        call    somethin(unsigned int)
        mov     edi, 1
        call    somethin(unsigned int)
        mov     edi, 2
        call    somethin(unsigned int)
        mov     edi, 3
        pop     rax
        jmp     somethin(unsigned int)            # TAILCALL

Leave a Reply

Your email address will not be published. Required fields are marked *