gprof 用 Eigen 声明了太多的“自发”
gprof declares too much as “spontaneous” with Eigen
我有一个使用特征矩阵库的 C++ 项目。为了提高性能,我需要为它获取配置文件。我试过使用 gprof,但是配置文件包含一堆这样的结果,它被标记为“自发的”:
<spontaneous>
[1] 48.8 2535.09 38010.25 GaugeField::read_lime_gauge_field_doubleprec_timeslices(double*, char const*, long, long) [1]
20857.12 0.00 3419496363/5297636514 Eigen::internal::gebp_kernel<std::complex<double>, std::complex<double>, long, Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0>, 1, 4, false, false>::operator()(Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0> const&, std::complex<double> const*, std::complex<double> const*, long, long, long, std::complex<double>, long, long, long, long) [2]
5844.01 11309.11 3350517373/3366570904 Eigen::internal::gebp_kernel<std::complex<double>, std::complex<double>, long, Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0>, 1, 4, true, false>::operator()(Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0> const&, std::complex<double> const*, std::complex<double> const*, long, long, long, std::complex<double>, long, long, long, long) [4]
有时直接呼叫 Eigen
被标记为自发的。
我 85% 的时间都花在标记为自发的部分上。这没什么用,因为我已经知道在我的张量收缩代码中,对 Eigen 的调用将是最昂贵的。我需要知道这些调用来自我代码的哪一部分。
有没有办法让 gprof 从我的程序中提取更多有用的信息?
似乎没有真正的方法可以在不删除所有优化的情况下使用普通 gprof 来解决这个问题。那当然会扭曲性能测量并且毫无用处。
最后我只写了一些代码,以分层方式跟踪调用。该程序现在在函数顶部定义了一堆 TimingScope<3>("Diagram::request");
对象。然后,它们会将自己注册为对单例的持续函数调用。然后该对象的析构函数将停止时间并将其添加到给定节点和边缘的时间,并从父节点的自身时间中推导出它。我使用 Python 脚本来生成输出,就像 gprof2dot 给出的那样:
如果 gprof 对我们有用,这使我们能够通过比 gprof 更多的上下文来理解程序。
我有一个使用特征矩阵库的 C++ 项目。为了提高性能,我需要为它获取配置文件。我试过使用 gprof,但是配置文件包含一堆这样的结果,它被标记为“自发的”:
<spontaneous>
[1] 48.8 2535.09 38010.25 GaugeField::read_lime_gauge_field_doubleprec_timeslices(double*, char const*, long, long) [1]
20857.12 0.00 3419496363/5297636514 Eigen::internal::gebp_kernel<std::complex<double>, std::complex<double>, long, Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0>, 1, 4, false, false>::operator()(Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0> const&, std::complex<double> const*, std::complex<double> const*, long, long, long, std::complex<double>, long, long, long, long) [2]
5844.01 11309.11 3350517373/3366570904 Eigen::internal::gebp_kernel<std::complex<double>, std::complex<double>, long, Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0>, 1, 4, true, false>::operator()(Eigen::internal::blas_data_mapper<std::complex<double>, long, 0, 0> const&, std::complex<double> const*, std::complex<double> const*, long, long, long, std::complex<double>, long, long, long, long) [4]
有时直接呼叫 Eigen
被标记为自发的。
我 85% 的时间都花在标记为自发的部分上。这没什么用,因为我已经知道在我的张量收缩代码中,对 Eigen 的调用将是最昂贵的。我需要知道这些调用来自我代码的哪一部分。
有没有办法让 gprof 从我的程序中提取更多有用的信息?
似乎没有真正的方法可以在不删除所有优化的情况下使用普通 gprof 来解决这个问题。那当然会扭曲性能测量并且毫无用处。
最后我只写了一些代码,以分层方式跟踪调用。该程序现在在函数顶部定义了一堆 TimingScope<3>("Diagram::request");
对象。然后,它们会将自己注册为对单例的持续函数调用。然后该对象的析构函数将停止时间并将其添加到给定节点和边缘的时间,并从父节点的自身时间中推导出它。我使用 Python 脚本来生成输出,就像 gprof2dot 给出的那样:
如果 gprof 对我们有用,这使我们能够通过比 gprof 更多的上下文来理解程序。