Tell gcc to specifically unroll a loop
Asked Answered
P

3

68

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.

Puklich answered 1/11, 2010 at 18:1 Comment(5)
Heh can you do it using macros? Probably not, so just writing it out is the only thing left?Puklich
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.Matador
You can wrap GCC's function attribute syntax in macros. I've done this once or twice for spot optimizations.Complementary
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 :-)Embody
Gcc now has a pragma: gcc.gnu.org/onlinedocs/gcc/…Asur
C
68

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.

Complementary answered 10/1, 2013 at 5:44 Comment(4)
Very cool that there is a function attribute for this, however it's ignored by Apple's latest GCC for iOS: "warning: 'optimize' attribute directive ignored". (I know they've transitioned to LLVM but I'm still using GCC sometimes, as it sometimes produces faster code.) Anyone know why it's ignored? Is Apple's GCC branch too old? On a side note, in the function on which I've been using it, loops get unrolled anyway as long as I use -O3.Influent
I just tried __attribute__((optimize("unroll-loops"))) with some embedded code and it improved speed by only 3%. Manually unrolling 8 times improved speed by 12% and didn't increase program size as much.Sikang
My gcc tells warning: ignoring #pragma optimize... Is this always available ?Capsulize
in case somebody else is wondering, both clang 3.9 and icc 13 don't support this attribute nor the pragmaBereave
O
73

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.

Optician answered 22/2, 2019 at 17:10 Comment(2)
Seems like the more correct/relevant answer for present day.Donets
Note that you need to enable some optimization option for this to work: "Most optimizations are completely disabled at -O0 or if an -O level is not set on the command line, even if individual optimization flags are specified. Similarly, -Og suppresses many optimization passes. " --- gcc manualRosmunda
C
68

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.

Complementary answered 10/1, 2013 at 5:44 Comment(4)
Very cool that there is a function attribute for this, however it's ignored by Apple's latest GCC for iOS: "warning: 'optimize' attribute directive ignored". (I know they've transitioned to LLVM but I'm still using GCC sometimes, as it sometimes produces faster code.) Anyone know why it's ignored? Is Apple's GCC branch too old? On a side note, in the function on which I've been using it, loops get unrolled anyway as long as I use -O3.Influent
I just tried __attribute__((optimize("unroll-loops"))) with some embedded code and it improved speed by only 3%. Manually unrolling 8 times improved speed by 12% and didn't increase program size as much.Sikang
My gcc tells warning: ignoring #pragma optimize... Is this always available ?Capsulize
in case somebody else is wondering, both clang 3.9 and icc 13 don't support this attribute nor the pragmaBereave
U
4

-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...

Urchin answered 1/11, 2010 at 18:7 Comment(3)
nah I found that too, but I want to just unroll a specific loopPuklich
bmei from broadcom have a set of patches to add "#pragma unroll" support to gcc.Averroes
@Jerry Coffin, How can I use it ? Can you give me a command which uses -funroll-loop ?Fibroma

© 2022 - 2024 — McMap. All rights reserved.