如何用C计算执行时间?

时间:2011-10-06 13:44:23

标签: c timing

如何在以下代码中计算执行时间:

#include <stdio.h>  /* Core input/output operations                         */
#include <stdlib.h> /* Conversions, random numbers, memory allocation, etc. */
#include <math.h>   /* Common mathematical functions                        */
#include <time.h>   /* Converting between various date/time formats         */
#include <sys/time.h>
#define PI      3.1415926535   /* Known vaue of PI                          */
#define NDARTS     128   /* Number of darts thrown                    */
double pseudo_random(double a, double b) {
double r;  /* Random number */
r = ((b - a) * ((double) rand()/(double) RAND_MAX)) + a;
 return r;
}
int main (int argc, char *argv[]) {
int    n_procs,       /* Number of processors                 */
llimit,        /* Lower limit for random numbers       */
ulimit,        /* Upper limit for random numbers       */
n_circle,      /* Number of darts that hit the circle  */
i;             /* Dummy/Running index                  */
double pi_sum,        /* Sum of PI values from each WORKER    */
x,             /* x coordinate, betwen -1 & +1         */
y,             /* y coordinate, betwen -1 & +1         */
z,             /* Sum of x^2 and y^2                   */
error;         /* Error in calculation of PI           */
clock_t start_time,    /* Wall clock - start time              */
end_time;      /* Wall clock - end time                */
struct timeval stime, starttime1, endtime1;
struct timeval tv1, tv2, diff;

llimit   = -1;
ulimit   = 1;
n_circle = 0;
printf("\n  Monte Carlo method of finding PI\n\n");
printf("    Number of processors : %d\n", n_procs);
printf("    Number of darts      : %d\n\n", NDARTS);
gettimeofday(&tv1, NULL);
gettimeofday(&stime, NULL);
srand(stime.tv_usec * stime.tv_usec * stime.tv_usec * stime.tv_usec);
for (i = 1; i <= NDARTS; i++) {
x = pseudo_random(llimit, ulimit);
y = pseudo_random(llimit, ulimit);
z = pow(x, 2) + pow(y, 2);
if (z <= 1.0) {
   n_circle++;
  }
}


pi_sum = 4.0 * (double)n_circle/(double)NDARTS;
pi_sum = pi_sum / n_procs;
error = fabs((pi_sum - PI)/PI) * 100;
gettimeofday(&tv2, NULL);
double timeval_subtract (result, x, y)
{
result = ((double)  x - (double) y ) / (double)CLOCKS_PER_SEC;
}
double result1 = timeval_subtract(&diff, &tv1, &tv2);
printf("    Known value of  PI   : %11.10f\n", PI);
printf("    Average value of PI  : %11.10f\n", pi_sum);
printf("    Percentage Error     : %10.8f\n", error);
printf("    Time   : \n", clock() );
printf("    Start Time   : \n",&tv1);
printf("    End Time   :\n", &tv2);
printf("    Time elapsed (sec)   : \n", result1 );
 return 0;
} 

我使用了timeval_subtract函数,当我执行代码时,我得到了:

Monte Carlo method of finding PI

Number of processors : 16372
Number of darts      : 128

Known value of  PI   : 3.1415926535
Average value of PI  : 0.0002004184
Percentage Error     : 99.99362048
Time   : 
Start Time   : 
End Time   :
Time elapsed (sec)   :

首先,我找不到找到处理器数量的错误(我必须得到1个处理器)。

第二个“这是最重要的一点”,为什么我的时间,开始时间,结束时间和时间都过空了?

4 个答案:

答案 0 :(得分:1)

因为您没有足够的格式字符串,所以需要以'%'开头的内容,例如:

printf("    Time   :%d \n", clock() );

答案 1 :(得分:1)

n_procs从未被初始化,被打印的16372值恰好是之前在堆栈中的值。

C标准库不提供查询处理器数量或高性能计时器的功能,因此您必须查看其他查询方法。例如,POSIX和Windows API都提供了这样的功能。

编辑:有关如何初始化n_procs的信息,请参阅Programmatically find the number of cores on a machine。看看你如何使用gettimeofday,你可能会使用一些unix变体; “n_procs = sysconf(_SC_NPROCESSORS_ONLN);”可能就是你想要的。

答案 2 :(得分:1)

试试这个:

printf("    Time   : %lu\n", clock() );
printf("    Start Time   : %lds %ldus\n", tv1.tv_sec, tv1.tv_usec);
printf("    End Time   : %lds %ldus\n", tv2.tv_sec, tv2.tv_usec);

并且:

double timeval_subtract (result, x, y)

使用以下命令以微秒为单位返回时差:

long timeval_subtract (struct timeval * result, struct timeval * x, struct timeval * y)
{
   long usec = x->tv_sec * 1000000L + x->tv_usec;
   usec -= (y->tv_sec * 1000000L + y->tv_usec);

   result->tv_sec = usec / 1000000L;
   result->tv_usec = usec % 1000000L;

   return usec;
}

根据两个日期xy的不同,函数timeval_subtract的返回值(不是result表示的值!)可能有误,由于溢出。

假设长为32位宽,这种溢出将发生大于4294s的差异,对于长度为64位(应该是64位机器的情况),溢出将在很久之后发生......; - )

答案 3 :(得分:0)

我会尝试以下方法:

int     timeval_subtract ( struct timeval *result, struct timeval *x, struct timeval *y ) {

    if ( x->tv_usec < y->tv_usec ) {
            int nsec = ( y->tv_usec - x->tv_usec ) / 1000000 + 1;
            y->tv_usec -= 1000000 * nsec;
            y->tv_sec += nsec;
    }
    if (x->tv_usec - y->tv_usec > 1000000) {
            int nsec = ( x->tv_usec - y->tv_usec ) / 1000000;
            y->tv_usec += 1000000 * nsec;
            y->tv_sec -= nsec;
    }

    result->tv_sec = x->tv_sec - y->tv_sec;
    result->tv_usec = x->tv_usec - y->tv_usec;

    return x->tv_sec < y->tv_sec;
}

void Start ( struct timeval *timer_profiling ) {
        if ( timer_profiling == NULL )   return;
        gettimeofday ( timer_profiling , NULL );
        return;
}

void End ( struct timeval *timer_profiling , char *msg ) {
        struct timeval res;
        struct timeval now;
        gettimeofday ( &now , NULL );

        if ( msg == NULL )      return;

        timeval_subtract ( &res , &now , timer_profiling );
        sprintf ( msg , "[ %ld,%.3ld ms]" , res.tv_sec*1000 + (long)round(res.tv_usec/1000) , res.tv_usec - (long)round(res.tv_usec/1000)*1000);

        return;
}

使用已分配的timer_profiling启动(&amp; s),然后通过调用End(&amp; s,buff)检索字符串中的结果;