7

我正在尝试在 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);
}
4

6 回答 6

19

三种选择

  1. clock()
  2. gettimeofday()
  3. clock_gettime()

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
于 2015-07-03T09:09:50.083 回答
7

注意: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;
}
于 2014-03-04T20:40:16.367 回答
4

首先,您需要使用浮点运算。任何整数值除以更大的整数值将始终为零。

当然,您实际上应该在获取开始时间和结束时间之间做一些事情。


顺便说一句,如果您可以访问gettimeofday它通常是首选,clock因为它具有更高的分辨率。或者可能clock_gettime具有更高的分辨率。

于 2013-02-04T08:25:58.837 回答
2

您编写的代码有两个问题。

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

  2. 这一行:

    millis = micros / 1000;
    

    会将商计算为整数,因为两个操作数都是整数。对浮点类型的提升发生在对 的赋值millis时,此时小数部分已被丢弃。

要使用 计算经过的秒数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()or 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_nsec / NANO_PER_SEC;
    elapsed_sec = end_sec - start_sec;
    printf("The operation took %.3f seconds\n", elapsed_sec);

    return 0;
}

由于NANO_PER_SEC是浮点数,除法运算以浮点数进行。

来源:、和
man的页面。C编程语言, Kernighan 和 Ritchieclock(3)gettimeofday(3)clock_gettime(3)

于 2016-10-16T17:51:01.087 回答
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;
于 2013-02-04T08:27:49.680 回答
1

尝试 Sunil D S 的答案,但将 micros 从 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 提供合理的精度。

于 2013-12-09T07:07:45.137 回答