测量linux中c程序的经过时间

时间:2013-02-04 08:21:25

标签: c linux time

我正在尝试测量Linux中的已用时间。我的回答一直归零,这对我来说毫无意义。以下是我在计划中测量时间的方式。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

main()
{
    double p16 = 1, pi = 0, precision = 1000;
    int k;
    unsigned long micros = 0;
    float millis = 0.0;
    clock_t start, end;
    start = clock();
    // This section calculates pi
    for(k = 0; k <= precision; k++)
    {
        pi += 1.0 / p16 * (4.0 / (8 * k + 1) - 2.0 / (8 * k + 4) - 1.0 / (8 * k + 5) - 1.0 / (8 * k + 6));
        p16 *= 16;
    }
    end = clock();
    micros = end - start;
    millis = micros / 1000;
    printf("%f\n", millis); //my time keeps being returned as 0

    printf("this value of pi is  : %f\n", pi);
}

6 个答案:

答案 0 :(得分:12)

三种选择

  1. clock()
  2. gettimeofday()
  3. clock_gettime()
  4. clock_gettime()精度达到纳秒级,支持4个时钟。

    • <强> CLOCK_REALTIME

      系统范围的实时时钟。设置此时钟需要适当的权限。

    • <强> CLOCK_MONOTONIC

      无法设置的时钟,表示自某些未指定的起点以来的单调时间。

    • <强> CLOCK_PROCESS_CPUTIME_ID

      来自CPU的高分辨率每进程计时器。

    • <强> CLOCK_THREAD_CPUTIME_ID

      特定于线程的CPU时钟。

    您可以将其用作

    #include <time.h>
    
    struct timespec start, stop;
    
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
    
    /// do something
    
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &stop);
    
    double result = (stop.tv_sec - start.tv_sec) * 1e6 + (stop.tv_nsec - start.tv_nsec) / 1e3;    // in microseconds
    

答案 1 :(得分:6)

注意:clock()函数返回进程的CPU时间,而不是挂钟时间。我相信这是OP感兴趣的。如果需要挂钟时间,那么gettimeofday()是一个很好的选择,如前面的答案所示。如果你的系统支持,clock_gettime()可以做任何一个;在我的linux嵌入式系统上不支持clock_gettime(),但是clock()和gettimeofday()是。

以下是使用gettimeofday()获取挂钟时间的代码

#include <stdio.h> // for printf()
#include <sys/time.h> // for clock_gettime()
#include <unistd.h> // for usleep()

int main() {
    struct timeval start, end;
    long secs_used,micros_used;

    gettimeofday(&start, NULL);
    usleep(1250000); // Do the stuff you want to time here
    gettimeofday(&end, NULL);

    printf("start: %d secs, %d usecs\n",start.tv_sec,start.tv_usec);
    printf("end: %d secs, %d usecs\n",end.tv_sec,end.tv_usec);

    secs_used=(end.tv_sec - start.tv_sec); //avoid overflow by subtracting first
    micros_used= ((secs_used*1000000) + end.tv_usec) - (start.tv_usec);

    printf("micros_used: %d\n",micros_used);
    return 0;
}

答案 2 :(得分:3)

首先,您需要使用浮点算术。任何整数值除以较大的整数值总是为零。

当然,你应该在获取开始和结束时间之间


顺便说一句,如果您有gettimeofday的访问权限,则通常优先于clock,因为它具有更高的分辨率。或者clock_gettime可能具有更高的分辨率。

答案 3 :(得分:1)

当你除法时,你可能会得到一个小数,因此你需要一个平滑点数来存储毫秒数。 如果不使用浮点,则会截断小数部分。在您的代码中,开头和结尾几乎相同。因此,存储在long中的除法后的结果是“0”。

unsigned long micros = 0;
float millis = 0.0;
clock_t start, end;

start = clock();

//code goes here

end = clock();

micros = end - start;
millis = micros / 1000;

答案 4 :(得分:1)

尝试Sunil D S的答案,但是将micro从unsigned long更改为float或double类型,如下所示:

double micros;
float seconds;

clock_t start, end;

start = clock();

/* Do something here */

end = clock();

micros = end - start;
seconds = micros / 1000000;

或者,您可以使用rusage,如下所示:

struct rusage before;

struct rusage after;

float a_cputime, b_cputime, e_cputime;

float a_systime, b_systime, e_systime;

getrusage(RUSAGE_SELF, &before);

/* Do something here! or put in loop and do many times */

getrusage(RUSAGE_SELF, &after);

a_cputime = after.ru_utime.tv_sec + after.ru_utime.tv_usec / 1000000.0;

b_cputime = before.ru_utime.tv_sec + before.ru_utime.tv_usec / 1000000.0;

e_cputime = a_cputime - b_cputime;

a_systime = after.ru_stime.tv_sec + after.ru_stime.tv_usec / 1000000.0;

b_systime = before.ru_stime.tv_sec + before.ru_stime.tv_usec / 1000000.0;

e_systime = a_systime - b_systime;


printf("CPU time (secs): user=%.4f; system=%.4f; real=%.4f\n",e_cputime, e_systime, seconds);

单位和精度取决于您想要测量的时间,但其中任何一个都应该 为ms提供合理的准确度。

答案 5 :(得分:0)

您的代码存在两个问题。

  1. 根据man 3 clockclock()的分辨率为每秒CLOCKS_PER_SEC个增量。在最近的Cygwin系统中,它是200.基于变量的名称,您期望值为1,000,000。

  2. 这一行:

    millis = micros / 1000;
    

    会将商计算为整数,因为两个操作数都是整数。在分配给millis时,升级到浮点类型,此时小数部分已被丢弃。

  3. 要使用clock()计算经过的秒数,您需要执行以下操作:

    clock_t start, end;
    float seconds;
    start = clock();
    // Your code here:
    end = clock();
    seconds = end - start; // time difference is now a float
    seconds /= CLOCKS_PER_SEC; // this division is now floating point
    

    但是,您几乎肯定不会达到毫秒精度。为此,您需要使用gettimeofday()clock_gettime()。此外,您可能希望使用double而不是float,因为您可能最终会减去非常大的数字,但差别很小。使用clock_gettime()的示例是:

    #include <time.h>
    /* Floating point nanoseconds per second */
    #define NANO_PER_SEC 1000000000.0
    
    int main(void)
    {
        struct timespec start, end;
        double start_sec, end_sec, elapsed_sec;
        clock_gettime(CLOCK_REALTIME, &start);
        // Your code here
        clock_gettime(CLOCK_REALTIME, &end);
        start_sec = start.tv_sec + start.tv_nsec/NANO_PER_SEC;
        end_sec = end.tv_sec + end.tv_n_sec/NANO_PER_SEC;
        elapsed_sec = end_sec - start_sec;
        printf("The operation took %.3f seconds\n", elapsed_sec);
        return 0;
    }
    

    由于NANO_PER_SEC是浮点值,因此除法运算以浮点形式执行。

    来源:
    manclock(3)gettimeofday(3)的{​​{1}}页 C 编程 语言,Kernighan和Ritchie