【问题标题】:How to reduce output size of template-heavy C++ code?如何减少模板繁重的 C++ 代码的输出大小?
【发布时间】:2012-10-04 15:38:22
【问题描述】:

我有一个大问题。我有一个通用库,在我的项目中使用。该库集中使用boost.spiritboost.fusion。不幸的是,图书馆大约是。 700Mb 大小。使用了所有boost.spirit-heavy 代码并且运行良好。可以采取哪些步骤来减小其输出大小?是否有工具可以帮助确定哪些模板实例化浪费了大部分空间?

起初,我决定将所有精神感知代码移动到 cpp 文件中。其次,我将尝试不同的编译器标志来优化大小。我不知道还能做什么。

更新(详情)

我正在使用 GNU 工具链。庞大的库实际上是一个静态库。使用这个 700Mb 库的可执行文件大小为 200Mb。至少有一半的代码在 *.h 文件中。一些boost.spirit 语法(非常重的模板)也位于*.h 文件中。

干杯!

【问题讨论】:

    标签: c++ templates boost-spirit


    【解决方案1】:

    将精神感知代码移动到.cpp 文件是一个很好的第一步,尽管您提到头文件中有精神语法,但它可能不完整。

    1. 确保没有任何语法/规则被导出到库之外。如果您有典型的 include/src 目录,则将这些文件(即使是标题)移动到 src 目录中。

    2. 将所有这些符号标记为库的内部符号。根本不应该从图书馆外访问它们。根据您的编译器,有特定的编译指示/属性,在 gcc 查找 visibility attribute:__attribute__ ((visibility ("internal")))。这有助于编译器相应地优化它们,特别是编译器可能会发出函数的代码,即使它在给定的调用站点内联它,以防万一这个函数地址被占用。然而,对于内部可见性,因为它知道代码不会离开对象,所以它可能会忽略函数。

    3. 我好像记得有一个标志可以融合相同的函数体,但似乎找不到了……

    【讨论】:

    • 感谢visibility 属性,不知道。
    【解决方案2】:

    --ffunction-sections 会将每个函数放在自己的段中。本身没有用,但链接器可以使用--gc-sections 删除未使用的部分。现在如果没有--ffunction-sections,这只会在整个源文件未被使用时才有效,即具有疯狂的粒度。

    显然您需要 Matthieu 提到的可见性属性,否则库中的所有函数都因可见而被“使用”。

    【讨论】:

      【解决方案3】:

      这里已经讨论过了:why my C++ output executable is so big?

      基本上,寻找调试符号,链接依赖的顺序,优化等等......

      【讨论】:

        【解决方案4】:

        一些建议:

          1234563 4 字节的 blob,所以一个可以委托给另一个,并且只是充当一个东西包装器,它只是转换回正确的类型,因此向量的内部只需要为一种类型实例化,而不是两种。
        • 尝试不同的编译器。一些编译器在不会影响程序语义的情况下重用相同的模板实例化,而另一些则更为保守。

        • 密切关注从库中导出的内容。链接器可以删除未导出且未在内部引用的符号。 (当然,如果您正在构建一个静态库,则在将其链接到可执行文件之前它不会启动。要减小库本身的大小,您可以尝试将其改为动态库)

        但最终,听起来您可能只需要使用模板较少的库。 (或者写一个比你现在更简单的解析器)

        【讨论】:

        • 重用模板实例化的一个问题是,通常每个函数都应该有不同的地址,这会阻止将不同的函数正确地融合在一起,即使它们的可执行代码不同。我不认为 VC++ 对此很在意,但是严格来说,这种优化只有在编译器可以证明程序中没有使用地址时才可用......
        • @MatthieuM。是的,这就是为什么不是所有编译器都这样做的原因。它通常是一个非常安全的优化(你不经常比较函数地址,当你这样做时,我怀疑在大多数情况下它是无效的,编译器检测它相当简单)——但是,它确实模板繁重代码的可执行大小的奇迹
        猜你喜欢
        • 1970-01-01
        • 2015-02-24
        • 2021-08-29
        • 2020-10-17
        • 1970-01-01
        • 1970-01-01
        • 2020-06-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多