告诉gcc专门展开一个循环

Nil*_*ils 47 c gcc pragma unroll

如何告诉GCC展开特定的循环?我使用过CUDA SDK,可以使用手动展开循环#pragma unroll.gcc有类似的功能吗?我用谷歌搜索了一下但找不到任何东西.

Phi*_*rad 54

GCC为您提供了几种不同的处理方式:

  • 使用#pragma指令一样#pragma GCC optimize ("string"...),如被看见在GCC文档.请注意,pragma使剩余函数的优化成为全局.如果你聪明地使用#pragma push_optionspop_options宏,你可能只围绕一个函数来定义它,如下所示:

    #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
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用GCC的属性语法注释单个函数:检查GCC函数属性文档以获取有关该主题的更详细的论文.一个例子:

    //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;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

注意:我不确定GCC在展开反向迭代循环方面有多好(我这样做是为了让Markdown与我的代码一起玩得很好).但是这些例子应该编译得很好.

  • 非常酷的是,有一个函数属性,但是它被 Apple 最新的 iOS GCC 忽略了:“警告:'优化'属性指令被忽略”。(我知道他们已经过渡到 LLVM,但有时我仍在使用 GCC,因为它有时会生成更快的代码。)有人知道为什么它被忽略了吗?苹果的 GCC 分支是不是太老了?附带说明一下,在我一直在使用它的函数中,只要我使用 -O3,循环就会展开。 (2认同)
  • 我刚刚尝试了 __attribute__((optimize("unroll-loops")))` 和一些嵌入式代码,它的速度仅提高了 3%。手动展开 8 次可将速度提高 12%,并且程序大小不会增加太多。 (2认同)
  • 如果有人想知道,clang 3.9 和 icc 13 都不支持此属性,也不支持 pragma (2认同)

Fre*_*rdt 6

GCC 8获得了新的实用性,可让您控制循环展开的方式:

#pragma GCC unroll n

从手册中引用:

您可以使用此编译指示来控制循环应展开的次数。必须将它放在for,while或do循环或#pragma GCC ivdep之前,并且仅适用于随后的循环。n是一个整数常数表达式,指定展开因子。0和1的值将阻止循环的任何展开。

  • 似乎是当今更正确/相关的答案。 (3认同)