59
votes

How can I tell GCC to unroll a particular loop? I have used the CUDA SDK where loops can be unrolled manually using #pragma unroll. Is there a similar feature for gcc? I googled a bit but could not find anything.

3
Heh can you do it using macros? Probably not, so just writing it out is the only thing left? - Nils
In all seriousness, I'd suggest looking into separate compilation of just that bit with -funroll-loops before using Duff's Device: it's a beautiful thing to study, but an ugly thing to have in your code. - dmckee --- ex-moderator kitten
You can wrap GCC's function attribute syntax in macros. I've done this once or twice for spot optimizations. - Philip Conrad
Upvoted @dmckee's comment but just have to add that "-funroll-loops" always sounds like the name of a cool roller-coaster at a theme park to me :-) - Vicky

3 Answers

62
votes

GCC gives you a few different ways of handling this:

  • Use #pragma directives, like #pragma GCC optimize ("string"...), as seen in the GCC docs. Note that the pragma makes the optimizations global for the remaining functions. If you used #pragma push_options and pop_options macros cleverly, you could probably define this around just one function like so:

    #pragma GCC push_options
    #pragma GCC optimize ("unroll-loops")
    
    //add 5 to each element of the int array.
    void add5(int a[20]) {
        int i = 19;
        for(; i > 0; i--) {
            a[i] += 5;
        }
    }
    
    #pragma GCC pop_options
    
  • Annotate individual functions with GCC's attribute syntax: check the GCC function attribute docs for a more detailed dissertation on the subject. An example:

    //add 5 to each element of the int array.
    __attribute__((optimize("unroll-loops")))
    void add5(int a[20]) {
        int i = 19;
        for(; i > 0; i--) {
            a[i] += 5;
        }
    }
    

Note: I'm not sure how good GCC is at unrolling reverse-iterated loops (I did it to get Markdown to play nice with my code). The examples should compile fine, though.

38
votes

GCC 8 has gained a new pragma that allows you to control how loop unrolling is done:

#pragma GCC unroll n

Quoting from the manual:

You can use this pragma to control how many times a loop should be unrolled. It must be placed immediately before a for, while or do loop or a #pragma GCC ivdep, and applies only to the loop that follows. n is an integer constant expression specifying the unrolling factor. The values of 0 and 1 block any unrolling of the loop.

4
votes

-funroll-loops might be helpful (though it turns on loop-unrolling globally, not per-loop). I'm not sure whether there's a #pragma to do the same...