time.h中的clock()精度

时间:2011-12-21 18:03:00

标签: c linux time clock

我正在尝试计算一个函数用来运行的滴答数,并使用clock()函数来计算,如下所示:

unsigned long time = clock();
myfunction();
unsigned long time2 = clock() - time;
printf("time elapsed : %lu",time2);

但问题是它返回的值是10000的倍数,我认为是CLOCK_PER_SECOND。是否存在更精确的方法或等效函数值?

我正在使用Ubuntu 64位,但是如果该解决方案可以在其他系统上工作,例如Windows& Mac OS。

4 个答案:

答案 0 :(得分:8)

POSIX中有许多更准确的计时器。

  • gettimeofday() - 官方过时,但可以广泛使用;微秒级分辨率。
  • clock_gettime() - gettimeofday()的替代品(但不一定如此广泛;在旧版本的Solaris上,需要-lposix4才能链接),具有纳秒分辨率。

还有其他亚秒级定时器具有更大或更小的古代,便携性和分辨率,包括:

  • ftime() - 毫秒级分辨率(在POSIX 2004中标记为“遗留”;不在POSIX 2008中)。
  • clock() - 您已经了解的内容。请注意,它测量的是CPU时间,而不是经过的(挂钟)时间。
  • times() - CLK_TCKHZ。请注意,这会测量父进程和子进程的CPU时间。

除非没有更好的内容,否则请勿使用ftime()times()。最终的后备,但不符合您的直接要求,是

  • time() - 一秒钟的决议。

clock()函数以CLOCKS_PER_SEC为单位报告,POSIX必须为1,000,000,但增量可能不太频繁发生(每秒100次是一个常见频率) 。返回值必须由CLOCKS_PER_SEC定义,以秒为单位获得时间。

答案 1 :(得分:1)

根据clock()手册页,在POSIX平台上,CLOCKS_PER_SEC宏的值必须是1000000.正如你所说,你从clock()获得的返回值是10000的倍数,这意味着分辨率是10毫秒。

另请注意,Linux上的clock()返回程序使用的处理器时间的近似值。在Linux上,再次调度程序统计信息在调度程序运行时以CONFIG_HZ频率更新。因此,如果周期性定时器滴答为100 Hz,则可获得10 ms分辨率的过程CPU时间消耗统计信息。

Walltime测量不受此限制,可以更准确。现代Linux系统上的clock_gettime(CLOCK_MONOTONIC,...)提供纳秒分辨率。

答案 2 :(得分:1)

测量时间的最精确(但非常可移植)的方法是计算CPU滴答声。

例如在x86上

 unsigned long long int asmx86Time ()
 {
   unsigned long long int realTimeClock = 0;
   asm volatile ( "rdtsc\n\t"         
                  "salq $32, %%rdx\n\t"    
                  "orq %%rdx, %%rax\n\t"   
                  "movq %%rax, %0"         
                  : "=r" ( realTimeClock ) 
                  : /* no inputs */
                  : "%rax", "%rdx" );
   return realTimeClock;
 }

 double cpuFreq ()
 {
   ifstream file ( "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" );
   string sFreq; if ( file ) file >> sFreq;
   stringstream ssFreq ( sFreq ); double freq = 0.;
   if ( ssFreq ) { ssFreq >> freq; freq *= 1000; } // kHz to Hz
   return freq;
 }

 // Timing

 unsigned long long int asmStart = asmx86Time ();
 doStuff ();
 unsigned long long int asmStop  = asmx86Time ();
 float asmDuration = ( asmStop - asmStart ) / cpuFreq ();

如果您没有x86,则必须根据CPU重新编写汇编程序代码。如果你需要最大精度,那不幸的是唯一的方法......否则使用clock_gettime()。

答案 3 :(得分:-1)

我同意乔纳森的解决方案。以下是具有纳秒精度的clock_gettime()的实现。

//Import 
 #define _XOPEN_SOURCE 500
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 #include <sys/time.h>


 int main(int argc, char *argv[])
 {   
     struct timespec ts;
     int ret;
     while(1)
     {
         ret = clock_gettime (CLOCK_MONOTONIC, &ts);
         if (ret) 
         {
             perror ("clock_gettime");
             return;
         }
         ts.tv_nsec += 20000; //goto sleep for 20000 n
         printf("Print before sleep tid%ld %ld\n",ts.tv_sec,ts.tv_nsec );
        // printf("going to sleep tid%d\n",turn );
         ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME,&ts, NULL);

     }
 }

虽然很难达到ns精度,但这可以用来获得不到一微秒(700-900 ns)的精度。上面的printf用于打印线程#(它只需要2-3微秒来打印一个语句)。