C程序的执行时间

时间:2011-03-09 16:32:30

标签: c benchmarking

我有一个C程序,旨在在多个处理器上并行运行。我需要能够记录执行时间(可能是1秒到几分钟)。我已经搜索了答案,但他们似乎都建议使用clock()函数,然后计算程序所用的时钟数除以Clocks_per_second值。

我不确定如何计算Clocks_per_second值?

在Java中,我只是在执行前后以毫秒为单位。

C中有类似的东西吗?我看过了,但我似乎无法找到比第二种解决方案更好的方法。

我也知道分析器是一个选项,但我希望自己实现一个计时器。

由于

16 个答案:

答案 0 :(得分:302)

CLOCKS_PER_SEC是一个在<time.h>中声明的常量。要获取C应用程序中任务使用的CPU时间,请使用:

clock_t begin = clock();

/* here, do your time-consuming job */

clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;

请注意,这会将时间作为浮点类型返回。这可能比一秒钟更精确(例如,您测量4.52秒)。精度取决于架构;在现代系统上,您可以轻松获得10毫秒或更低的速度,但在较旧的Windows机器上(从Win98时代开始)它接近60毫秒。

clock()是标准C;它“无处不在”。系统特定的功能,例如类Unix系统上的getrusage()

Java的System.currentTimeMillis()并没有衡量同样的事情。它是一个“挂钟”:它可以帮助您测量程序执行所花费的时间,但它并不能告诉您使用了多少CPU时间。在多任务系统(即所有这些系统)上,这些系统可能大不相同。

答案 1 :(得分:106)

如果您正在使用Unix shell运行,则可以使用time命令。

$ time ./a.out

假设a.out作为可执行文件将给你运行这个

的时间

答案 2 :(得分:56)

你在功能上想要这个:

#include <sys/time.h>

struct timeval  tv1, tv2;
gettimeofday(&tv1, NULL);
/* stuff to do! */
gettimeofday(&tv2, NULL);

printf ("Total time = %f seconds\n",
         (double) (tv2.tv_usec - tv1.tv_usec) / 1000000 +
         (double) (tv2.tv_sec - tv1.tv_sec));

请注意,这是以微秒为单位,而不仅仅是秒。

答案 3 :(得分:54)

普通香草C:

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

int main()
{
    clock_t tic = clock();

    my_expensive_function_which_can_spawn_threads();

    clock_t toc = clock();

    printf("Elapsed: %f seconds\n", (double)(toc - tic) / CLOCKS_PER_SEC);

    return 0;
}

答案 4 :(得分:12)

大多数简单程序的计算时间以毫秒为单位。所以,我想,你会觉得这很有用。

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

int main(){
    clock_t start = clock();
    // Execuatable code
    clock_t stop = clock();
    double elapsed = (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC;
    printf("Time elapsed in ms: %f", elapsed);
}

如果您想计算整个程序的运行时并且您使用的是Unix系统,请使用time ./a.out这样的time命令运行程序

答案 5 :(得分:9)

很多答案都建议来自clock()的{​​{1}}然后CLOCKS_PER_SEC。这可能是一个坏主意,因为这是我的time.h文件所说的:

/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 # if !defined __STRICT_ANSI__ && !defined __USE_XOPEN2K /* Even though CLOCKS_PER_SEC has such a strange value CLK_TCK presents the real value for clock ticks per second for the system. */ # include <bits/types.h> extern long int __sysconf (int); # define CLK_TCK ((__clock_t) __sysconf (2)) /* 2 is _SC_CLK_TCK */ # endif 可能被定义为1000000,具体取决于您用于编译的选项,因此它似乎不是一个好的解决方案。

答案 6 :(得分:7)

Thomas Pornin作为宏的回答:

#define TICK(X) clock_t X = clock()
#define TOCK(X) printf("time %s: %g sec.\n", (#X), (double)(clock() - (X)) / CLOCKS_PER_SEC)

像这样使用:

TICK(TIME_A);
functionA();
TOCK(TIME_A);

TICK(TIME_B);
functionB();
TOCK(TIME_B);

输出:

time TIME_A: 0.001652 sec.
time TIME_B: 0.004028 sec.

答案 7 :(得分:4)

您必须考虑到,衡量执行程序的时间在很大程度上取决于机器在特定时刻的负载。

知道了,在C中获取当前时间的方式可以通过不同方式实现,更容易实现:

#include <time.h>

#define CPU_TIME (getrusage(RUSAGE_SELF,&ruse), ruse.ru_utime.tv_sec + \
  ruse.ru_stime.tv_sec + 1e-6 * \
  (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec))

int main(void) {
    time_t start, end;
    double first, second;

    // Save user and CPU start time
    time(&start);
    first = CPU_TIME;

    // Perform operations
    ...

    // Save end time
    time(&end);
    second = CPU_TIME;

    printf("cpu  : %.2f secs\n", second - first); 
    printf("user : %d secs\n", (int)(end - start));
}

希望它有所帮助。

问候!

答案 8 :(得分:3)

ANSI C仅指定第二个精确时间函数。但是,如果您在POSIX环境中运行,则可以使用gettimeofday()函数,该函数提供自UNIX纪元以来经过的微秒分辨率。

作为旁注,我不推荐使用clock(),因为它在很多(如果不是全部?)系统上实现得很糟糕而且不准确,除了它只指你的程序花了多长时间。 CPU,而不是程序的总生命周期,根据你的问题,我认为你想测量。

答案 9 :(得分:3)

(如果您的系统管理员更改了系统时间,或者您的时区有不同的冬季和夏季时间,则此处的所有答案都缺少。因此......)

在linux上使用:clock_gettime(CLOCK_MONOTONIC_RAW, &time_variable); 如果系统管理员改变时间,或者你生活在一个冬季时间与夏季时间不同的国家,它不会受到影响。

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

#include <unistd.h> /* for sleep() */

int main() {
    struct timespec begin, end;
    clock_gettime(CLOCK_MONOTONIC_RAW, &begin);

    sleep(1);      // waste some time

    clock_gettime(CLOCK_MONOTONIC_RAW, &end);

    printf ("Total time = %f seconds\n",
            (end.tv_nsec - begin.tv_nsec) / 1000000000.0 +
            (end.tv_sec  - begin.tv_sec));

}

man clock_gettime州:

CLOCK_MONOTONIC
              Clock  that  cannot  be set and represents monotonic time since some unspecified starting point.  This clock is not affected by discontinuous jumps in the system time
              (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.

答案 10 :(得分:2)

每个解决方案都无法在我的系统中运行。

我可以使用

#include <time.h>

double difftime(time_t time1, time_t time0);

答案 11 :(得分:2)

    #include<time.h>
    #include<stdio.h>
    int main(){
clock_t begin=clock();

    int i;
for(i=0;i<100000;i++){
printf("%d",i);

}
clock_t end=clock();
printf("Time taken:%lf",(double)(end-begin)/CLOCKS_PER_SEC);
}
  

这个程序会像魅力一样工作。

答案 12 :(得分:1)

我发现,每个人都建议在这里使用通常的clock(),由于某种原因,即使在没有任何副作用的静态代码(例如绘制到屏幕或读取文件)的情况下,每次运行也会有很大差异。可能是因为CPU改变了功耗模式,操作系统赋予了不同的优先级,等等...

因此,每次使用clock()可靠地获得相同结果的唯一方法是多次(在几分钟内)在循环中运行被测代码,并采取预防措施以防止编译器对其进行优化:现代编译器可以预计算没有循环影响的代码,然后将其移出循环。例如,每次迭代都使用随机输入。

在将足够多的样本收集到一个数组中之后,对数组进行排序,然后获取中间元素(称为中值)。中位数比平均水平要好,因为它可以消除极端偏差,例如说杀毒软件占用了所有CPU或操作系统进行了一些更新。

这是一个简单的实用程序,用于测量C / C ++代码的执行性能,将中值https://github.com/saniv/gauge附近的值平均化

我自己仍在寻找一种更健壮,更快速的方法来测量代码。可以尝试在没有任何操作系统的裸机上在受控条件下运行代码,但这会产生不切实际的结果,因为实际上OS确实参与其中。

x86具有这些硬件性能计数器,其中包括实际执行的指令数量,但是在没有OS帮助的情况下它们很难访问,难以解释并且有自己的问题(http://archive.gamedev.net/archive/reference/articles/article213.html)。他们仍然可以帮助研究瓶颈的本质(数据访问或对该数据的实际计算)。

答案 13 :(得分:0)

perf工具更加准确,可以用来收集和分析正在运行的程序。使用perf stat显示与正在执行的程序有关的所有信息。

答案 14 :(得分:-1)

有些人可能会发现另一种有用的输入:我将这种测量时间的方法作为使用NVidia CUDA(course description)进行GPGPU编程的大学课程的一部分。它结合了先前文章中看到的方法,我之所以简单地发布它是因为要求赋予了它可信性:

unsigned long int elapsed;
struct timeval t_start, t_end, t_diff;
gettimeofday(&t_start, NULL);

// perform computations ...

gettimeofday(&t_end, NULL);
timeval_subtract(&t_diff, &t_end, &t_start);
elapsed = (t_diff.tv_sec*1e6 + t_diff.tv_usec);
printf("GPU version runs in: %lu microsecs\n", elapsed);

我想你可以乘以1.0 / 1000.0获取适合您需求的计量单位。

答案 15 :(得分:-2)

冒泡排序和选择排序的执行时间比较 我有一个程序,它比较冒泡排序和选择排序的执行时间。 要找出执行代码块的时间,请计算

之前和之后的时间
 clock_t start=clock();
 …
 clock_t end=clock();
 CLOCKS_PER_SEC is constant in time.h library

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
   int a[10000],i,j,min,temp;
   for(i=0;i<10000;i++)
   {
      a[i]=rand()%10000;
   }
   //The bubble Sort
   clock_t start,end;
   start=clock();
   for(i=0;i<10000;i++)
   {
     for(j=i+1;j<10000;j++)
     {
       if(a[i]>a[j])
       {
         int temp=a[i];
         a[i]=a[j];
         a[j]=temp;
       }
     }
   }
   end=clock();
   double extime=(double) (end-start)/CLOCKS_PER_SEC;
   printf("\n\tExecution time for the bubble sort is %f seconds\n ",extime);

   for(i=0;i<10000;i++)
   {
     a[i]=rand()%10000;
   }
   clock_t start1,end1;
   start1=clock();
   // The Selection Sort
   for(i=0;i<10000;i++)
   {
     min=i;
     for(j=i+1;j<10000;j++)
     {
       if(a[min]>a[j])
       {
         min=j;
       }
     }
     temp=a[min];
     a[min]=a[i];
     a[i]=temp;
   }
   end1=clock();
   double extime1=(double) (end1-start1)/CLOCKS_PER_SEC;
   printf("\n");
   printf("\tExecution time for the selection sort is %f seconds\n\n", extime1);
   if(extime1<extime)
     printf("\tSelection sort is faster than Bubble sort by %f seconds\n\n", extime - extime1);
   else if(extime1>extime)
     printf("\tBubble sort is faster than Selection sort by %f seconds\n\n", extime1 - extime);
   else
     printf("\tBoth algorithms have the same execution time\n\n");
}