在C语言中如何测量经过的时间?

4

所以,我想看一下我的代码中的某个函数需要多长时间才能运行(实时)。

最初我的代码是这样的:

clock_t begin = clock();
my_function();
clock_t end = clock();
double time_spent = (double)(end - begin);

但显然,这种方法存在一些问题。

  1. 它仅测量CPU处理我的应用程序所花费的时间。
  2. 从我所看到的来看,它只以微秒为单位进行测量,这对我的情况不够精确。

那么,获取函数运行所需时间的正确方法是什么?CPU时间真的是正确的方法吗?我能测量多精确?我在考虑纳秒级别?


2
对于实时性,您可以使用gettimeofday,但无法达到纳秒级别,而且您可能不在实时系统上,因此即使是毫秒级别实际上也超出了您可以期望的有效精度。 - bruno
@bruno 我明白了。当基准测试函数的运行时,实时方式是首选吗? - Kyu96
1
@bruno:在拥有它的系统上,gettimeofday已经被弃用,而是使用clock_gettime(它具有纳秒分辨率,但测量诸如几十ns之类的实际开销)。而乱序执行意味着您无法可靠地计时小于该时间的定时区域,除非您了解您的CPU,并使用x86 lfence; rdtsc来控制OoO exec。请参见Idiomatic way of performance evaluation?关于微小定时区域的内容。 - Peter Cordes
2个回答

5

所以,你应该问自己是否真的需要纳秒级别。处理器以GHz级别的时钟频率运行,这意味着指令执行需要大约纳秒的时间。这意味着纳秒精度极其复杂(如果不是不可能)进行测量。

C11带有新的timespec_get可以以纳秒分辨率获取时间,但它肯定不那么准确。

如果您的目标是测量函数的执行时间,则最好的选择是在循环中调用函数,像执行它一千次,并使用微秒精度来测量它,这肯定比任何声称具有纳秒精度的计时器更接近于纳秒精度。


公正的观点。是的,我认为微秒可能已经足够了 - 然后在多次迭代之后得到平均值。我假设实时是衡量函数运行时间的常见方式,对吗? - Kyu96
@Kyu96 不,我认为实时性不是最好的选择,因为它通常只有1秒的精度。这个问题很有启发性 https://dev59.com/jHRC5IYBdhLWcg3wP-n5#368843 ,我会应用第二个答案来解决你的问题,该答案基于时钟滴答数来测量时间。 - Puck
2
循环调用将测量吞吐量。或者,如果您使下一个输入依赖于上一个输出,则测量延迟。微基准测试很难,并且有时必须小心,以获得优化的代码,而不会让编译器优化掉您想要测量的内容。相关:性能评估的惯用方式? - Peter Cordes
Puck: @Kyu96 问是否以挂钟时间(又称实时时间)作为衡量标准,而不是由操作系统记录的进程 CPU 时间。你可以高精度地测量任一时间。我通常用时钟周期来测量东西,所以在控制 CPU 频率缩放方面可能会稍微有些粗心,只要它不太依赖于内存带宽或延迟。如果你要测量的东西没有进行任何 I/O 操作,在一个空闲系统上,其中没有上下文切换可以从你的进程中窃取时间,挂钟时间和 CPU 时间基本上是等效的。中断不计入... - Peter Cordes

4
C标准没有定义一种可移植的方法来实现这一点。time()库函数有一个1秒的定义,这对您的目的来说不合适。正如@Puck所提到的,C11引入了timespec_get()来检索更精确的时间值,但是此函数并不广泛支持,可能无法提供预期的准确性。
其他功能在选定的系统上可用:

请注意,进行精确可靠的亚微秒基准测试是一项非常困难的任务,这一点不容忽视。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接