clock()在time.h中的精度

我试图计算一个函数用来运行的滴答数量,并使用clock()函数来这样做:

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

但问题是它返回的值是10000的倍数,我认为是CLOCK_PER_SECOND 。 有没有更精确的方法或等价的函数值?

我使用Ubuntu 64位,但宁愿如果解决scheme可以在Windows和Mac OS等其他系统上工作。

Solutions Collecting From Web of "clock()在time.h中的精度"

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

  • gettimeofday() – 正式过时,但可用性非常广泛; 微秒的分辨率。
  • clock_gettime() – 取代gettimeofday() (但不一定是如此广泛的可用;在旧版本的Solaris上,需要-lposix4链接),以纳秒的分辨率。

还有其他亚秒级的古代,可移植性和解决方案的计时器,其中包括:

  • ftime() – 毫秒分辨率(在POSIX 2004中标记为“legacy”;不在POSIX 2008中)。
  • clock() – 你已经知道了。 请注意,它测量CPU时间,而不是经过(挂钟)时间。
  • times()CLK_TCKHZ 。 请注意,这会测量父进程和子进程的CPU时间。

除非没有更好的东西,否则不要使用ftime()times() 。 最终的后备,但不符合你的直接要求是

  • time() – 一秒钟的分辨率。

clock()函数以CLOCKS_PER_SEC为单位进行报告,POSIX要求为1,000,000 ,但增量的发生频率可能​​较低(每秒100次是一个常用频率)。 返回值必须由CLOCKS_PER_SEC定义,以秒为单位获得时间。

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

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

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

测量时间的最精确(但非常便携)的方法是计算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()。

我同意乔纳森的解决方案。 这里是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微秒)。