C语言中clock()函数的精度



我有一些代码试图确定代码块的执行时间。

#include <time.h>
#include <stdio.h>
int main()
{
   clock_t start_t, end_t, total_t;
   int i;
   start_t = clock(); //clock start
   printf("Starting of the program, start_t = %ldn", start_t);
   printf("Going to scan a big loop, start_t = %ldn", start_t);
   for(i=0; i< 10000000; i++)  //trying to determine execution time of this block
   {
   }
   end_t = clock(); //clock stopped
   printf("End of the big loop, end_t = %ldn", end_t);
   total_t = (long int)(end_t - start_t);
   printf("Total time taken by CPU: %lun", total_t  );
   return(0);
}

这个代码片段在我的机器上的输出是

Starting of the program, start_t = 8965
Going to scan a big loop, start_t = 8965
End of the big loop, end_t = 27259
Total time taken by CPU: 18294

所以如果我的CPU运行在21mhz并且假设这是唯一要执行的事情,每个机器周期将大约等于47纳秒,所以(18294 * 47)= 859818纳秒。

这是我代码中for循环的执行时间吗?我是不是做了一些错误的假设?

clock函数使用的时间单位是任意的。在大多数平台上,它与处理器速度无关。它通常与外部定时器中断的频率有关(可以在软件中配置),或者与经过多年处理器演变而保持兼容性的历史值有关。您需要使用宏CLOCKS_PER_SEC来转换为实时。

printf("Total time taken by CPU: %fsn", (double)total_t / CLOCKS_PER_SEC);

C标准库被设计成可在各种硬件上实现,包括没有内部计时器和依赖外部外设来显示时间的处理器。许多平台有比time更精确的测量时钟时间的方法,也有比clock更精确的测量CPU消耗的方法。例如,在POSIX系统(例如Linux和其他类unix系统)上,您可以使用getrusage,它具有微秒级精度。

struct timeval start, end;
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
start = usage.ru_utime;
…
getrusage(RUSAGE_SELF, &usage);
end = usage.ru_utime;
printf("Total time taken by CPU: %fsn", (double)(end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1e-6);

在可用的情况下,clock_gettime(CLOCK_THREAD_CPUTIME_ID)clock_gettime(CLOCK_PROCESS_CPUTIME_ID)可以提供更好的精度。它有纳秒级的精度。

注意precision和accuracy之间的区别:precision是报告值的单位。准确性是指报告值与实际值的接近程度。除非您在一个实时系统上工作,否则对于一段代码需要多长时间是没有硬性保证的,包括度量函数本身的调用。

一些处理器有周期时钟来计算处理器周期而不是时钟时间,但这是非常系统特定的。

无论何时进行基准测试,都要注意,您测量的是特定情况下特定CPU上特定可执行文件的执行情况,结果可能适用于也可能不适用于其他情况。例如,问题中的空循环将被大多数编译器优化掉,除非您关闭优化。测量未优化代码的速度通常是没有意义的。即使您在循环中添加了实际的工作,也要注意玩具基准测试:它们通常不具有与实际代码相同的性能特征。在PC和智能手机等现代高端CPU上,CPU密集型代码的基准测试通常对缓存效果非常敏感,其结果可能取决于系统上运行的其他内容,确切的CPU模型(由于不同的缓存大小和布局),以及代码恰好加载的地址等。

相关内容

  • 没有找到相关文章

最新更新