在 linux 中测量 ac 程序的运行时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14682824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:55:09  来源:igfitidea点击:

Measuring elapsed time in linux for a c program

clinuxtime

提问by Hyman welch

I am trying to measure elapsed time in Linux. My answer keeps returning zero which makes no sense to me. Below is the way i measure time in my program.

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

采纳答案by Some programmer dude

To start with you need to use floating point arithmetics. Any integer value divided by a larger integer value will be zero, always.

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

And of course you should actually dosomething between getting the start and end times.

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



By the way, if you have access to gettimeofdayit's normally preferred over clockas it has higher resolution. Or maybe clock_gettimewhich has even higher resolution.

顺便说一句,如果您可以访问gettimeofday它,通常会优先考虑clock它,因为它具有更高的分辨率。或者也许clock_gettime哪个具有更高的分辨率。

回答by Sunil D S

When you divide, you might end up with a decimal, hence you need a flaoting point number to store the number of milli seconds. If you don't use a floating point, the decimal part is truncated. In your piece of code, the start and end are ALMOST the same. Hence the result after division when stored in a long is "0".

除法时,您可能会得到一个小数,因此您需要一个浮点数来存储毫秒数。如果不使用浮点数,小数部分将被截断。在您的一段代码中,开始和结束几乎相同。因此,当存储在 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;

回答by Wiley

Try Sunil D S's answer but change micros from unsigned long to type float or double, like this:

尝试 Sunil DS 的答案,但将 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;

Alternatively, you could use rusage, like this:

或者,您可以使用 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);

Units and precision depend on how much time you want to measure but either of these should provide reasonable accuracy for ms.

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

回答by grubs

Note: The clock() function returns CPU time for your process, not wall clock time. I believe this is what the OP was interested in. If wall clock time is desired, then gettimeofday() is a good choice as suggested by an earlier answer. clock_gettime() can do either one if your system supports it; on my linux embedded system clock_gettime() is not supported, but clock() and gettimeofday() are.

注意:clock() 函数返回进程的 CPU 时间,而不是挂钟时间。我相信这是 OP 感兴趣的内容。如果需要挂钟时间,那么 gettimeofday() 是一个不错的选择,正如之前的答案所建议的那样。如果您的系统支持,clock_gettime() 可以执行任一操作;在我的 linux 嵌入式系统上,clock_gettime() 不受支持,但 clock() 和 gettimeofday() 支持。

Below is the code for getting wall clock time using 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;
}

回答by Shreevardhan

Three alternatives

三种选择

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

clock_gettime()goes upto nanosecond accuracy and it supports 4 clocks.

clock_gettime()精度达到纳秒级,支持 4 个时钟。

  • CLOCK_REALTIME

    System-wide realtime clock. Setting this clock requires appropriate privileges.

  • CLOCK_MONOTONIC

    Clock that cannot be set and represents monotonic time since some unspecified starting point.

  • CLOCK_PROCESS_CPUTIME_ID

    High-resolution per-process timer from the CPU.

  • CLOCK_THREAD_CPUTIME_ID

    Thread-specific CPU-time clock.

  • CLOCK_REALTIME

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

  • CLOCK_MONOTONIC

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

  • CLOCK_PROCESS_CPUTIME_ID

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

  • CLOCK_THREAD_CPUTIME_ID

    线程特定的 CPU 时间时钟。

You can use it as

您可以将其用作

#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

回答by Jim Schneider

There are two issues with your code as written.

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

  1. According to man 3 clock, the resolution of clock()is in CLOCKS_PER_SECincrements per second. On a recent-ish Cygwin system, it's 200. Based on the names of your variables, you are expecting the value to be 1,000,000.

  2. This line:

    millis = micros / 1000;
    

    will compute the quotient as an integer, because both operands are integers. The promotion to a floating-point type occurs at the time of the assignment to millis, at which point the fractional part has already been discarded.

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

  2. 这一行:

    millis = micros / 1000;
    

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

To compute the number of seconds elapsed using clock(), you need to do something like this:

要使用 计算经过的秒数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

However, you will almost certainly not get millisecond accuracy. For that, you would need to use gettimeofday()or clock_gettime(). Further, you probably want to use doubleinstead of float, because you are likely going to wind up subtracting very large numbers with a very tiny difference. The example using clock_gettime()would be:

但是,您几乎肯定不会获得毫秒精度。为此,您需要使用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_nsec / NANO_PER_SEC;
    elapsed_sec = end_sec - start_sec;
    printf("The operation took %.3f seconds\n", elapsed_sec);

    return 0;
}

Since NANO_PER_SECis a floating-point value, the division operations are carried out in floating-point.

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

Sources:
manpages for clock(3), gettimeofday(3), and clock_gettime(3).
TheCProgrammingLanguage, Kernighan and Ritchie

来源:
manclock(3)gettimeofday(3)clock_gettime(3)
Ç编程语言,Kernighan和Ritchie