测量代码执行时间的“快速”方法

Posted

技术标签:

【中文标题】测量代码执行时间的“快速”方法【英文标题】:"Fast" way to measure code execution time 【发布时间】:2018-12-11 12:11:20 【问题描述】:

我的代码中有一些子例程,我需要测量它们的执行时间。假设在极端情况下,例程每秒被调用 10-100 次。在 Fortran 中有很多方法可以测量时间,但由于调用的频率,我需要一种开销最低的方法。

时间测量本身不需要非常准确,因为我对子程序花费几毫秒或更短时间的情况不感兴趣,而是当它们飙升到 50 毫秒或更多时(这是我需要采取反制措施并在内部重新平衡一些事情)。

代码是使用 MPI+OpenMP 并行化的,所以MPI_Wtime() 将是最简单的方法,但我想这会带来相当大的成本?我对一个好的解决方案的猜测是system_clock()。有谁知道每秒调用 50-100 次是否“安全”(性能方面)?

【问题讨论】:

我猜这个有相当大的成本?我对一个好的解决方案的猜测是 system_clock() 当涉及到性能测量数据时,每次都胜过猜测。如果这是您关心的问题,为什么您还没有测量它? 你说得对。问题是我担心构建一个代码 sn-p 来衡量不同时序例程的影响,这会受到编译器优化和类似事情的支配。使用实际代码来衡量实际测试用例中的影响将需要花费数十万核心小时,这是非常不理想的。因此,我希望有人可能对这个问题有一些经验。 你为什么不设置一个分析器,做一批(100,000或更多?)操作,然后才测量时间? 听从 Rodigo 的建议。大多数(如果不是全部)编译器都带有分析器。在 linux/FreeBSD 上使用 gfortran,使用 -pg 选项和 gprof 程序来解密输出。 @HighPerformanceMark 我并没有说你不能从精心设计的测试中获得这些数据。你是100%正确的。问题是我怀疑我设置这样一个测试的能力,它可以产生正确的数据,不受任何测试设计错误的影响;) 【参考方案1】:

system_clock 可能比cpu_time 便宜得多,并且精度更高。

对于 Linux 上的 GFortran,我依稀记得我曾经在循环中调用它进行测试,system_clock 每次调用大约需要 50 ns。

对于 Linux 上的 GFortran,system_clockclock_gettime(CLOCK_MONOTONIC, ...) 的包装器,(在 Linux 上它使用 vDSO 而不是真正的系统调用,因此它非常快),libgomp 中的 omp_get_wtime 也是如此(OpenMP 运行时库GFortran 使用的),所以这两者的性能应该差不多。

我不确定MPI_Wtime 是如何在常见的 MPI 实现上实现的,但如果它是相同的,我不会感到惊讶。

【讨论】:

我在 Cray Fortran 编译器手册中找到了以下语句:A call to the SYSTEM_CLOCK intrinsic subroutine with the COUNT argument present translates into the inline instructions that directly access the hardware clock register. [...] The CPU_TIME subroutine obtains the value of its argument from the getrusage system call. Its execution time is significantly longer than for the SYSTEM_CLOCK routine, but the values returned are closer to those used by system accounting utilities. 所以你关于system_clock 更便宜的说法似乎是正确的。

以上是关于测量代码执行时间的“快速”方法的主要内容,如果未能解决你的问题,请参考以下文章

如何测量预编译的 java 类的执行时间?

使用 Unity 拦截测量方法执行时间

Javascript:在线测量代码执行时间

c ++测量执行时间

测量代码段的 Java 执行时间、内存使用和 CPU 负载

如何以可靠的方式测量执行一段代码所花费的时间?