如何在 Linux 上的 clang 中获取模板实例化统计信息?

How to get templates instantiation statistics in clang on Linux?

提问人:CurDev 提问时间:11/6/2023 最后编辑:CurDev 更新时间:11/6/2023 访问量:117

问:

我正在探索 C++ 中模板的不同方面,并希望更深入地探讨这个主题。

例如,我在一些头文件中有一个非常简单的函数模板:

template<typename T>
void foo(T value)
{
    (void)value;
}

我想获得在构建一些代码期间实例化了多少时间的统计信息。 好吧,也许获得这种统计数据会很复杂。在构建一些代码期间,大量的模板实例化(10 次、20 次等)就足够了。

例如,我有 follings 文件:和 . 我完成了构建过程,并希望获得统计信息。a.ha.cppb.hb.cppc.hc.cppmain.cppCMakeLists.txt

我试图分析使用选项执行 clang build 的输出,但这不是我想要的。它更多的是关于编译不同部分的执行时间和百分比,它与具体的翻译单元有关。-ftime-report

是否有可能获得这些统计数据?

C Linux Clang Clang++

评论

0赞 Fareanor 11/6/2023
@CurDev 也许你可以用每一个(唯一)遇到的容器填充一个容器,然后计算出现次数。typeid(T)
0赞 HolyBlackCat 11/6/2023
OP,您想计算模板使用的唯一模板参数的数量吗?或者您还想包含不同翻译单元的重复实例化?
0赞 user12002570 11/6/2023
@HolyBlackCat 该注释仍然没有说明如何在构建某些代码期间测量实例化的时间。尽管可以在没有任何外部工具的情况下回答 OP 的问题。
0赞 CurDev 11/6/2023
@HolyBlackCat 我想在此计数中包括不同翻译单元的重复实例化。
0赞 R2RT 11/6/2023
尽管我认为这是有效的问题,我希望有人会回答,但你也可以在 LLVM 的 Github 上问同样的问题,标记为问题:github.com/llvm/llvm-project/......

答:

3赞 HolyBlackCat 11/6/2023 #1

如果仅实例化的数量就足够了(而不是花在它们上的时间),这应该有效:

#include <cstddef>
#include <iostream>
#include <utility>

inline int &GetCounter()
{
    static int ret = 0;
    return ret;
}

template <typename T>
static const auto register_type = []{
    GetCounter()++;
    return nullptr;
}();

template <typename T>
void foo(T value)
{
    (void)value;

    // Instantiate `register_type<T>`.
    (void)std::integral_constant<const std::nullptr_t *, &register_type<T>>{};
}

int main()
{
    std::cout << GetCounter() << '\n'; // 3

    if (false)
    {
        foo(1);
        foo(1.2);
        foo(1.2);
        foo(1.2f);
        foo(1.2f);
    }
}

请注意变量,它允许我们计算由不同 TU 完成的重复实例化。staticregister_type

我相信这也意味着在技术上违反了一个定义规则(因为在每个 TU 中它使用不同的变量),但这在实践中不应该引起任何问题,因为当链接器对这些实例进行重复数据删除时,选择哪一个并不重要,因为无论如何它们都会编译到同一个程序集。foo()register_type


如果您确实需要花时间在实例化上,我相信 Clang 是您的最佳选择。我会为每个 TU 运行它,然后以某种方式组合结果。-ftime-trace