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

glibc函数的GCC、-flto、-fno内置函数和自定义函数实现

  •  1
  • kreuzerkrieg  · 技术社区  · 7 年前

    我观察到了GCC标志的意外行为(至少我找不到解释) -flto jemalloc / tcmalloc . 一次 -flto公司 je/tc malloc 实现,则调用glibc实现。一旦我离开 旗子,一切正常。我试着用 -fno-builtin -fno-builtin-* 但它仍然没有选择 实施。

    怎么了 -flto公司 当它在未解决的外部问题上失败时, printf ?

    编辑001:
    合同一般条款7.3

    int main()
    {
        auto p = malloc(1024);
        free(p);
        return 0;
    }
    

    汇编:

    /usr/bin/c++-O2-g-DNDEBUG-flto-std=gnu++14-o /主页/用户/开发/cppfunk/flto/主.cpp

    联动装置:

    -o flto-L/home/user/Development/jemalloc-Wl,-rpath,/home/user/Development/jemalloc-ljemalloc

    编辑002:
    更合适的示例代码

    #include <cstdlib>
    
    int main()
    {
        auto p = malloc(1024);
        if (p) {
            free(p);
        }
    
        auto p1 = new int;
        if (p1) {
            delete p1;
        }
    
        auto p2 = new int[32];
        if (p2) {
            delete[] p2;
        }
        return 0;
    }
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Basile Starynkevitch    7 年前

    首先,您的示例代码是错误的。仔细阅读C11标准 n1570 . 当你想使用 标准 malloc #include <stdlib.h> .

    在C++ 11中(读) n3337 ) 马洛克 不赞成,不应使用(首选 new ). 如果你还想用 std::malloc 在C++中你应该 #include <cstdlib> (在GCC中,内部包括 <stdlib.h> )

    那么您的示例代码几乎就是C代码(一旦您替换了 auto void* ),而不是C++。可能是的 optimized (一旦你包括 <stdlib.h> ),甚至 -flto 但是有了正义 -O3 as-if 规则,到一个空的 main bismon-chariot-doc.pdf ,其中有一节§1.4.2在几页中解释了优化是如何发生的)。

    优化 free __attribute__(malloc) function attribute 在声明中(内部 <stdlib.h> )的 .

    LTO的说明见 GCC internals §25 .

    GIMPLE -喜欢和/或 SSA -like)代码在“编译”和“链接”时的表示(实际上,链接步骤变成了另一个整个程序优化的编译,因此您的代码在实践中“编译”了两次)。

    LTO公司 总是 -O2 甚至是 -臭氧 具有 g++ -flto -O2 (没有实际意义 -flto公司 至少 以及 完全相同 优化标志应该在编译和链接时使用)。

    更准确地说 也在对象文件中嵌入一些内部( -like)源代码的表示,它也用于“链接时”(特别是 optimization inlining 当“链接”你的 整个的 lto1 (除了C++前端和编译器调用 cc1plus )以及 是(当你 链接 g++-flto-氧气 )在链接时用于重新处理这些GIMPLE表示。

    libjemalloc 有自己的标题,而且可能 inline (或不可输入)函数。那么你还需要使用 -flto -O2

    最后,事实上 马洛克 -flto公司 . 这是一个链接器问题,而不是编译器问题。你可以试着联系 -ljemalloc 静态地(然后你最好用 gcc -flto -O2 ;如果不这样构建,就无法实现LTO优化 电话)。

    你也可以通过 -v 去你的编译和链接命令来理解什么 g++ 正在做。你甚至可以通过 -Wl,--verbose ld (开始人

    注意,LTO(以及它所使用的内部表示)是编译器和版本特定的。内部(Gimple& )代表是 轻微地 GCC 7 &安培; GCC 8 非常 ld-linux(8) 不知道LTO。

    另外,你可以安装 libjemalloc-dev #include <jemalloc/jemalloc.h> jemalloc(3) 利伯杰马洛克 可以配置或修补以定义 je_malloc . 那么(对于LTO)使用起来会更简单 杰马洛克 在你的代码中(为了避免 ELF 符号)。要了解有关共享库中符号的更多信息,请阅读Drepper's How to Write Shared Libraries

    推荐文章