为什么C clock()返回0

时间:2012-03-26 11:13:35

标签: c linux clock

我有这样的事情:

clock_t start, end;
start=clock();

something_else();

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

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

知道为什么会这样吗?

(只是为了给出一些细节,something_else()函数使用montgomery表示执行从左到右的取幂,而且我不确定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

7 个答案:

答案 0 :(得分:7)

clock函数不测量CPU时钟周期。

C说clock “将实现的最佳近似值返回给处理器 自实施定义时代开始以来该计划使用的时间 只对程序调用。“

如果在两个连续的clock次调用之间,您的程序花费的时间少于clock函数的一个整数,则可以获得0

POSIX clockCLOCKS_PER_SEC的统一定义为1000000(统一则为1微秒)。

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

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

答案 1 :(得分:6)

我想原因是你的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++;
        }
    }
    end = clock();
    printf("start = %d, end = %d\n", start, end);
    return 0;
}

我计算机上的结果是:

start = 0, end = 27700000

另外,有两个提示:

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

答案 2 :(得分:5)

嗯,你想要时间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;
}

答案 3 :(得分:2)

检查CLOCKS_PER_SECtime.h/clock.h的值。例如,在我的系统上(Windows 7上的Dev Cpp),仅仅1000。因此,就我的程序而言,每秒有1000个滴答。您的something_else将在几微秒内执行。因此clock()在函数调用之前和之后都返回零。

在我的系统上,当我用这样一个耗时的例程替换你的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()

的返回值之前,请考虑这一点

答案 4 :(得分:2)

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

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

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

答案 5 :(得分:1)

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

在我的测试系统上打印

CLOCKS_PER_SEC 1000000

CPU time usage resolutio n看起来像0.010000 seconds

当CPU时间由9634 uS

更改时,

gettimeofday由0.010000更改

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));

}

答案 6 :(得分:1)

在尝试使用向量在C ++和g ++编译器的Red Hat Linux上计时通用类和非通用类之间的差异时遇到了相同的问题。 如果您的程序运行速度比单个时钟慢,则会显示clock()读数始终为零(0)。

此代码将始终返回0

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    cout << clock() << endl;

    return 0;
}

当我添加一个索引高达一千万的for循环以降低程序速度时,我从clock()的结果中得到了20000

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    for (int i = 0; i < 10000000; i++) {}
    cout << clock() << endl;

    return 0;
}

在某些情况下,结果肯定会有所不同,我正在使用多处理器Xeon CPU和大量RAM运行此代码。