为什么C clock()返回0

我有这样的东西:

clock_t start, end; start=clock(); something_else(); end=clock(); printf("\nClock cycles are: %d - %d\n",start,end); 

我总是得到一个输出“时钟周期是:0 – 0”

任何想法为什么发生这种情况

(只是为了提供一些细节,something_else()函数使用蒙哥马利表示来执行从左到右的求幂,而且我不确定something_else()函数确实需要一些不能忽略的时间。)

这是在Linux上。 uname -a的结果是:

Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

Solutions Collecting From Web of "为什么C clock()返回0"

clock功能不会测量CPU时钟周期。

C表示“从实现定义的时代的开始,仅仅与程序调用相关的时间”返回实现对程序使用的处理器时间的最佳近似

如果在两个连续的clock调用之间,你编程的时间比一个clock函数的单位时间少,你可以得到0

POSIX clockCLOCKS_PER_SEC的单位定义为1000000(单位为1微秒)。

http://pubs.opengroup.org/onlinepubs/009604499/functions/clock.html

要测量x86 / x64中的时钟周期,可以使用内联汇编来检索CPU时间戳计数器寄存器rdtsc的时钟计数。

我猜这是因为你的something_else()消耗的时间太少,超过了clock()的精度 。 我试着两次调用clock() ,所以startend都是零,但是当我做了一些耗时的事情之后,结果是合理的。

这是我的测试代码片段:

 int main(void) { clock_t start, end; start = clock(); int c; for (int i = 0; i < 100; i++) { for (int j = 0; j < (1<<30); j++) { c++; } } printf("start = %d, end = %d\n", start, end); return 0; } 

而我的电脑上的结果是:

 start = 0, end = 27700000 

另外,两个提示:

  1. 测试时, 不要使用任何编译器优化 。 你可能认为你的something_else()是耗时的,但编译器可能会忽略这些操作(特别是循环),因为它认为它们毫无意义。
  2. 在您的平台上使用sizeof(clock_t)来查看clock_t的大小。

那么,你想要something_else()时间something_else()需要? 尝试这个:

 #include <sys/time.h> #include <stdio.h> #include <unistd.h> int main(void) { struct timeval start, end; long mtime, secs, usecs; gettimeofday(&start, NULL); something_else(); gettimeofday(&end, NULL); secs = end.tv_sec - start.tv_sec; usecs = end.tv_usec - start.tv_usec; mtime = ((secs) * 1000 + usecs/1000.0) + 0.5; printf("Elapsed time: %ld millisecs\n", mtime); return 0; 

}

使用clock()来测量时间的正确方法是:

 printf("\nTime elapsed: %.2f\n",1.0*(end-start)/CLOCKS_PER_SEC); 

这是因为clock_t不能保证是一个int,或者其他任何类型的。

time.h/clock.h检查CLOCKS_PER_SEC的值。 在我的系统上,例如(Windows 7上的Dev Cpp),它只有1000 。 所以就我的程序而言,每秒钟有1000个刻度。 你的something_else会在几微秒内被执行。 因此clock()在函数调用之前和之后都返回零。

在我的系统上,当我用something_else一个耗时的例程替换你的something_else

 for (unsigned i=0xFFFFFFFF;i--;); start=clock(); for (unsigned i=0xFFFFFFFF;i--;); end=clock(); 

我明白了

时钟周期是:10236 – 20593

在Linux的一个盒子里,我找到了下面的bits/time.h

 /* ISO/IEC 9899:1990 7.12.1: <time.h> The macro `CLOCKS_PER_SEC' is the number per second of the value returned by the `clock' function. */ /* CAE XSH, Issue 4, Version 2: <time.h> The value of CLOCKS_PER_SEC is required to be 1 million on all XSI-conformant systems. */ # define CLOCKS_PER_SEC 1000000l 

因此,在分析clock()的返回值之前,

我使用下面的小程序来调查挂钟时间和CPU时间。

在我的测试系统上打印

CLOCKS_PER_SEC 1000000

CPU time usage resolutio0.010000 seconds

当CPU时间更改0.010000时,gettimeofday更改为9634 uS

gettimeofday决议看起来是1 us

 #include <stdio.h> #include <unistd.h> #include <sys/time.h> #include <ctime> int main(int argc, char** argv) { struct timeval now; // wall clock times struct timeval later; clock_t tNow = clock(); // clock measures CPU time of this Linux thread gettimeofday(&now, NULL); // wall clock time when CPU time first read clock_t tLater = tNow; while (tNow == tLater) tLater = clock(); // consume CPU time gettimeofday(&later, NULL); // wall clock time when CPU time has ticked printf("CLOCKS_PER_SEC %ld\n",CLOCKS_PER_SEC); double cpuRes = (double)(tLater - tNow)/CLOCKS_PER_SEC; printf("CPU time usage resolution looks to be %f seconds\n", cpuRes); unsigned long long nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL; nowUs += (unsigned long long)now.tv_usec; unsigned long long laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL; laterUs += (unsigned long long)later.tv_usec; printf("gettimeofday changed by %d uS when CPU time changed by %f seconds\n", (int)(laterUs - nowUs), cpuRes); // now measure resolution of gettimeofday gettimeofday(&now, NULL); later = now; while ((now.tv_sec == later.tv_sec) && (now.tv_usec == later.tv_usec)) gettimeofday(&later, NULL); nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL; nowUs += (unsigned long long)now.tv_usec; laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL; laterUs += (unsigned long long)later.tv_usec; printf("gettimeofday resolution looks to be %d us\n", (int)(laterUs - nowUs)); }