分析模板元程序编译时间

idu*_*ree 21 c++ profiling instantiation template-meta-programming

我正在开发一个具有大量编译时计算的C++项目.漫长的编译时间正在减慢我们的速度.我怎样才能找到模板元程序中最慢的部分,以便我可以优化它们?(当我们有慢运行时计算时,我有很多分析器可供选择,例如valgrind的callgrind工具.所以我尝试构建一个调试GCC并分析它编译我们的代码,但我没有从中学到太多东西.)

我使用GCC和Clang,但欢迎任何建议.

profile_templates在Boost的网站上找到了,但似乎记录很少,需要jam/bjam构建系统.如果您展示如何在非卡纸项目1上使用它,我会向您投票.https://svn.boost.org/svn/boost/sandbox/tools/profile_templates/似乎计算实例数,而计算所花费的时间将是理想的.

1 我们的项目使用CMake并且足够小,只需将模板分析用于模板分析就可以接受.

Mik*_*son 15

我知道这是一个老问题,但我想给出一个更新的答案.

有一组基于clang的项目针对这一特定问题.第一个组件是clang编译器上的一个工具,它生成编译期间发生的所有模板实例化的完整跟踪,包括时序值和可选的内存使用计数.该工具称为Templight,可在此处访问(目前需要针对修补的clang源树进行编译):

https://github.com/mikael-s-persson/templight

第二个组件是一个转换工具,允许您将templight轨迹转换为其他格式,例如易于解析的基于文本的格式(yaml,xml,文本等)以及可以更容易可视化的格式,例如graphviz/graphML,更重要的是一个callgrind输出,可以加载到KCacheGrind中,以可视化和检查模板实例化的元调用图及其编译时成本,例如一段代码的模板实例化配置文件的屏幕截图创建一个boost::container::vector并对其进行排序std::sort:

在此输入图像描述

看看这里:

https://github.com/mikael-s-persson/templight-tools

最后,还有另一个相关项目,它创建了一个交互式shell和调试器,以便能够以交互方式在模板实例化图形中上下移动:

https://github.com/sabel83/metashell


Den*_*nis 8

自2008年以来,我一直在使用模板元编程的库.真正需要更好的工具或方法来理解消耗最多编译时间的内容.

我所知道的唯一技术是分而治之的方法,可以通过将代码分成不同的文件,注释掉模板定义的主体,或者将模板实例包装在#define宏中,并暂时重新定义这些宏来做任何事情.然后,您可以使用和不使用各种实例来重新编译项目并缩小范围.

顺便说一句,只是将相同的代码分成更多,更小的文件可能会使编译速度更快.我不只是谈论并行编译的机会 - 即使是连续编译,我发现它仍然更快.我在编译我的库时以及编译Boost Spirit解析器时都在gcc中观察到了这种效果.我的理论是,gcc中的一些符号解析,重载决策,SFINAE或类型推断代码在游戏中类型定义或符号的数量方面具有O(n log n)或甚至O(n ^ 2)的复杂度.在执行单位.

最终你需要做的是仔细检查你的模板并分离真正依赖于类型信息的内容,并尽可能使用类型擦除和虚拟函数,而不是实际上需要模板类型的代码部分.如果可以移动代码部分,需要从头文件和cpp文件中获取内容.在一个完美的世界中,编译器应该能够自己解决这个问题 - 您不必手动移动此代码来保护它 - 但这是我们今天使用的编译器的最新技术.