代码之家  ›  专栏  ›  技术社区  ›  Lou

纯函数的GCC优化

  •  6
  • Lou  · 技术社区  · 9 年前

    pure online docs ):

    pure
    

    许多函数除了返回值之外没有任何影响,它们的返回值仅取决于参数和/或全局变量。 (...)

    有趣的 非纯 feof 在多线程环境中)。

    对于 const

    const
    

    许多函数不检查除参数外的任何值,并且除返回值外没有任何影响。基本上,这只是比下面的纯属性稍微严格一点的类,因为函数不允许读取全局内存。

    请注意,不能声明具有指针参数并检查指向的数据的函数 常数 。同样,调用非常量函数的函数通常不能是常量。

    因此,我尝试创建一个接受指针参数的函数,并尝试标记它 .但是,我尝试使用GCC online编译此函数(我尝试了两者 ):

    typedef struct
    {
        int32_t start;
        int32_t end;
    }
    Buffer;
    
    inline __attribute__((pure,always_inline)) int32_t getLen(Buffer * b) 
    {
        return b->end - b->start;
    }
    

    并注意到GCC(至少几个 online compiler versions 我试过):

    1. 不优化 如果通过,则调用此函数(即多次调用) Buffer*
    2. 优化 调用此函数(即仅调用一次),如果
    3. 而不是 ,但据推测 常数

    Buffer 在本地 缓冲器 对于优化来说是完全安全的。

    纯净的 接受指针参数的函数?

    2 回复  |  直到 9 年前
        1
  •  6
  •   ecatmur    9 年前

    对于接受指针参数的纯函数,是否有明确定义GCC行为的地方?

    这种行为与不接受指针参数的纯函数没有什么不同;它们可以读取程序中的任何内存,但不能写入内存或执行IO。

    通过内联编写pure和const函数,您已经把事情弄糊涂了;如果调用站点的编译器可以使用函数体,那么它可以自行确定被调用函数执行的操作。当函数体不可见时,pure和const属性最有用,因为它将在单独的编译单元中定义。

    __attribute__((__pure__)) int a();
    __attribute__((__const__)) int b();
    void c();
    

    如果我们打电话 a 连续两次,在没有操作干预的情况下,我们可以将其折叠为一个调用,因为 保证只在读取时访问全局内存;即使另一个线程大约在同一时间写入全局内存,也没有办法 与该线程通信,以便编译器可以假设写入发生在两个调用之前或之后 :

    int f() {
        int i = a();
        i += a();
        return i;  // optimized to "return a() * 2;"
    }
    

    如果我们打电话 c 通话之间 c

    int g() {
        int i = a();
        c();
        i += a();
        return i;  // no optimization possible
    }
    

    然而,如果不是纯粹的 b ,我们可以将其折叠为一个调用,因为 b 无法读取任何 c

    int h() {
        int i = b();
        c();
        i += b();
        return i;  // optimized to "c(); return b() * 2;"
    }
    
        2
  •  1
  •   MSalters    9 年前

    “GCC作出的保证”。

    pure const 属性是 承诺 按GCC制造。

    可以 纯净的 常数