我知道这个问题可能已经被问过很多次,但是似乎大多数问题都涉及基于壁钟的代码流逝时间。代码块的流逝时间通常不等于实际执行时间,因为在感兴趣的代码流逝时间期间可能会执行其他进程。
我使用了getrusage()来获取进程的用户时间和系统时间,然后通过(用户时间+系统时间)计算出实际执行时间。我正在Ubuntu上运行我的程序。以下是我的问题:
- 我如何知道getrusage()的精度?
- 是否有其他方法可以比getrusage()提供更高的精度?
我知道这个问题可能已经被问过很多次,但是似乎大多数问题都涉及基于壁钟的代码流逝时间。代码块的流逝时间通常不等于实际执行时间,因为在感兴趣的代码流逝时间期间可能会执行其他进程。
我使用了getrusage()来获取进程的用户时间和系统时间,然后通过(用户时间+系统时间)计算出实际执行时间。我正在Ubuntu上运行我的程序。以下是我的问题:
你可以通过利用内核的CPU时间功能,在Linux上检查一个进程的实际CPU时间:
#include <time.h>
clock_t start, end;
double cpu_time_used;
start = clock();
... /* Do the work. */
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
来源: http://www.gnu.org/s/hello/manual/libc/CPU-Time.html#CPU-Time
这样,您可以计算进程所使用的 CPU 时钟周期或实际被 CPU 处理的指令数量,从而获得实际工作时间。
clock()
可能是最好的解决方案,因为它可以基于最佳系统调用进行实现,但这取决于具体实现。根据Linux clock(3)手册:“在glibc 2.17及更早版本中,clock()是基于times(2)实现的。为了提高精度,自glibc 2.18以来,它是基于clock_gettime(2)实现的(使用CLOCK_PROCESS_CPUTIME_ID时钟)。” - vinc17getrusage()函数是我所知道的获取“已消耗CPU时间”的唯一标准/可移植方式。
目前没有简单的方法来确定返回值的精度。我建议先调用getrusage()获取初始值,然后重复调用它,直到返回的值与初始值不同为止,然后假设有效精度是初始值和最终值之间的差异。这虽然有些取巧(精度可能高于此方法确定的值,并且结果可能被视为最坏情况下的估计),但总比没有好。
我还担心返回值的准确性。在某些内核下,当定时器IRQ发生时,计数器会增加任意正在运行的代码;因此,一个进程可能非常幸运(并连续阻塞在定时器IRQ发生之前),或非常不幸(并在定时器IRQ发生之前解除阻止)。在这种情况下,“幸运”可能意味着CPU占用高的看起来像没有使用CPU时间,“不幸”可能意味着使用非常少的CPU时间的进程看起来像CPU占用很高。
针对特定体系结构/版本的特定内核(取决于内核在某些情况下是否使用特定配置选项进行编译),可能存在更高精度的非标准可移植替代品...
#include <sys/time.h>
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()
来测量墙上时钟时间,所以被踩了。OP要求CPU时间(即当进程未执行时,经过的时间计数器应停止)。 - Matthew Cole