如何获取代码中函数调用所用时间的可靠计时数据?

计算科学 表现 分析
2021-12-01 22:01:01

这个问题是 Fortran 的后续问题:对代码部分进行计时的最佳方式?.

如果我想在我的代码中计时函数,我知道我可以使用 gprof 或 kcachegrind。我也知道这些工具的结果可能会出现偏差(请参阅http://www.yosefk.com/blog/how-profilers-lie-the-cases-of-gprof-and-kcachegrind.htmlhttps:// stackoverflow.com/questions/1777556/alternatives-to-gprof/1779343#1779343)。

我知道我可以为我想要数据的每个函数添加手动计时器,如果我想要所有东西的数据,这对于库来说可能是乏味或不切实际的。

不幸的是,我遇到了一些社区,他们希望这些时间数据用作证明他们的方法性能的证据(以证明性能的改进,指出性能不佳的地方,科学论文等等)。这似乎在管理类型和一些学术类型中很受欢迎。有没有比插入计时器更好的方法来获得可靠准确的计时数据?我是否应该结合使用不完善的工具并以某种方式筛选性能数据?

注意:这个问题性能调整无关,即使它是相关的。您可以通过使用随机暂停来进行性能调整而无需计时。这也与计时是否值得,因为这些社区需要计时数据,而且我没有能力轻易改变他们的想法。关于这些主题的任何评论都是很好的讨论,但它们对回答我的问题没有帮助,因为现实是我回答的人想要以某种方式反映的计时数据表现。)

3个回答

您可能会考虑使用像 HPCToolkit 或 VTune 这样的堆栈采样分析器,或者用于 Linux 的系统分析器 prof。

另外,我看不出想知道事情需要多长时间有什么不妥之处。如果您想证明您的算法实现具有您推导出的渐近性能,那么实际测量运行时间是最好的方法。

虽然 gprof 或 valgrind 的 cachegrind 可能确实会产生偏差的结果,但它们几乎总是足以满足您真正想做的事情 - 即找出哪些功能“昂贵”,哪些功能“不昂贵”。正如您引用的文章所示,有可能生成分析器无法显示整个故事的程序,或者实际上甚至显示错误。但是,当您将配置文件应用于“真实程序”时,它们几乎总是可以让您对事实有一个相当好的了解,这正是它们仍然被使用的原因。

换句话说,尽管存在局限性,但我确实相信,当应用于现实世界的程序时,配置文件确实显示了非常有用的数据,我会毫不犹豫地将这些数据包含在出版物中(并简要说明所述限制)。

我经常使用英特尔的 VTune 放大器来获得精确的时序,在正确的硬件上,它会将时序分解到指令级。更好的结果来自使用片上计数器,即性能监控单元。

计数仍然不准确,但比您从基于软件的收集器中获得的分辨率要好得多。

至于您对需要确切数字的评论,我不完全同意。我不认为自己是一个 bean 计数器,但我非常依赖计时器,主要是直接在代码中使用cycle.h从 FFTW的调用直接在宏中实现,用于实际研究。具体来说,我研究基于任务的并行算法,并且需要对花费在实际工作上的时间与任务分配中的开销进行良好的估计。这些开销通常是许多小函数调用的总和,并且很难在分析器中评估,但几乎是衡量调度方案好坏的唯一衡量标准。在这种情况下,精确的计时器实际上是做好研究的必要条件。