如何在Linux下测量C程序的实际执行时间?

16 浏览
0 Comments

如何在Linux下测量C程序的实际执行时间?

我知道这个问题可能以前常被问到,但大多数问题似乎涉及代码的经过的时间(根据墙上的时钟)。代码的经过的时间不太可能等于实际的执行时间,因为在代码感兴趣的经过的时间期间可能会有其他进程在执行。

我使用getrusage()获取进程的用户时间和系统时间,然后通过(用户时间+系统时间)计算实际执行时间。我在Ubuntu上运行我的程序。以下是我的问题:

  1. 我如何知道getrusage()的精度?
  2. 是否有其他方法可以提供比getrusage()更高的精度?
0
0 Comments

在Linux下,要测量C程序的实际执行时间,可以利用内核的CPU时间功能。这种方法通过使用clock()函数来计算进程的实际CPU时间,从而得到实际的工作时间。具体的实现代码如下:

#include 
clock_t start, end;
double cpu_time_used;
start = clock();
... /* Do the work. */
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;

通过调用clock()函数两次,可以计算出两次调用之间进程消耗的CPU时间。这种方法可以计算出CPU执行的指令数量或者CPU的时钟周期数,从而得到实际的工作时间。

然而这种方法可能会包括其他进程消耗的时间,而不仅仅是调用进程消耗的时间。但是,根据Linux的文档,CPU时间是相对于一个进程的,而不是整个系统的。因此,我们可以认为这种方法只计算了调用进程消耗的CPU时间。

在64位机器上,clock()函数可能是最好的解决方法,因为它可以在最佳的系统调用上实现。根据Linux的clock(3)手册页,从glibc 2.18开始,clock()函数是基于clock_gettime(2)函数实现的,使用的是CLOCK_PROCESS_CPUTIME_ID时钟。

,要测量C程序的实际执行时间,可以使用clock()函数来计算进程消耗的CPU时间。这种方法可以得到实际的工作时间,但可能会包括其他进程消耗的时间。对于64位机器来说,clock()函数可能是最佳的解决方法。

0
0 Comments

问题的出现原因:在Linux系统下,我们想要测量C程序的实际执行时间,但是常用的gettimeofday()函数只能测量墙钟时间,而不能测量CPU时间。

解决方法:下面给出了一段代码,可以用来测量C程序的实际执行时间。这段代码使用了sys/time.h头文件中的gettimeofday()函数来获取程序的开始时间和结束时间,并通过计算差值来得到实际执行时间。

#include 
struct timeval start, end;
gettimeofday(&start, NULL);
.
.
.
gettimeofday(&end, NULL);
delta = ((end.tv_sec  - start.tv_sec) * 1000000u +
         end.tv_usec - start.tv_usec) / 1.e6;
printf("Time is : %f\n",delta);

这段代码可以在你的程序中插入,它会显示出程序执行的时间。通过获取开始时间和结束时间的差值,并将其转换为秒,我们可以得到程序的实际执行时间。

需要注意的是,这段代码使用的是gettimeofday()函数来测量墙钟时间,而不是CPU时间。如果我们希望测量CPU时间,需要使用其他的方法。

0
0 Comments

问题出现的原因是在Linux系统下,没有一个简单的方法来测量C程序的实际执行时间。作者提到了getrusage()函数是目前他所知的唯一标准/可移植的方法来获取“消耗的CPU时间”。然而,getrusage()函数返回的值的精度无法确定,所以作者提出了一种解决方法:先调用getrusage()函数一次,获取初始值,然后重复调用该函数,直到返回的值与初始值不同,然后假设有效精度为初始值和最终值之间的差异。这种方法虽然是一种权宜之计(精度可能比此方法确定的要高,并且结果可能被认为是最坏情况的估计),但总比没有好。作者还提到对返回值的准确性表示担忧。在某些内核下,当计时器中断发生时,一个计数器会被递增,无论运行的是哪段代码。因此,一个进程有可能非常幸运(在计时器中断发生之前不断阻塞),或者非常不幸(在计时器中断发生之前不断解除阻塞)。在这种情况下,“幸运”可能意味着一个CPU占用量很高的进程看起来没有使用任何CPU时间,“不幸”可能意味着一个使用非常少CPU时间的进程看起来像一个CPU占用量很高的进程。对于特定版本的特定内核以及特定架构(在某些情况下,可能还取决于内核是否以特定配置选项进行编译),可能存在非标准、非可移植的高精度替代方法。

0