Fix for time measurement. No dependence on OMP, correct functions are used for each purpose.

Elapsed time can use gettimeofday(), times(), ftime().
CPU time can use getrusage(), times() and fall back to elapsed.
Replaced HAVE_UTIMES with HAVE_TIMES - probably typo and reason 
HAVE_TIMES was missing.
This commit is contained in:
caand 2020-07-28 18:01:46 +02:00
parent 5854344d20
commit fc445c2b0a
5 changed files with 102 additions and 153 deletions

View File

@ -787,14 +787,10 @@ AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stddef.h sys/file.h sys/param
AC_HEADER_TIME AC_HEADER_TIME
AC_STRUCT_TM AC_STRUCT_TM
AC_STRUCT_TIMEZONE AC_STRUCT_TIMEZONE
AC_CHECK_FUNCS([localtime]) AC_CHECK_FUNCS([localtime time])
AC_CHECK_FUNCS([ftime gettimeofday]) AC_CHECK_FUNCS([gettimeofday times ftime], [break])
# Do not use time or getrusage function for CPU time measurement under OpenMP AC_CHECK_FUNCS([getrusage times], [break])
if test "x$enable_openmp" != xyes; then
AC_CHECK_FUNCS([time getrusage])
fi
AC_CHECK_FUNCS([utimes])
AC_CHECK_FUNCS([getrlimit ulimit], [break]) AC_CHECK_FUNCS([getrlimit ulimit], [break])
AC_CHECK_FUNCS([endpwent gethostbyname memset select socket strdup strerror strncasecmp strstr strtol]) AC_CHECK_FUNCS([endpwent gethostbyname memset select socket strdup strerror strncasecmp strstr strtol])

View File

@ -22,7 +22,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include <inttypes.h> #include <inttypes.h>
#include "../misc/misc_time.h" /* timediff */ #include "../misc/misc_time.h" /* timebegin */
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - include ipc stuff */ /* gtri - add - 12/12/90 - wbk - include ipc stuff */
@ -81,15 +81,7 @@ init_rlimits(void)
void void
init_time(void) init_time(void)
{ {
#ifdef HAVE_GETRUSAGE timebegin();
#else
# ifdef HAVE_TIMES
# else
# ifdef HAVE_FTIME
ftime(&timebegin);
# endif
# endif
#endif
} }
@ -162,12 +154,12 @@ printres(char *name)
#endif #endif
bool yy = FALSE; bool yy = FALSE;
static bool called = FALSE; static bool called = FALSE;
static long last_sec = 0, last_msec = 0; static double last_sec = 0;
struct variable *v, *vfree = NULL; struct variable *v, *vfree = NULL;
char *cpu_elapsed; char *cpu_elapsed;
if (!name || eq(name, "totalcputime") || eq(name, "cputime")) { if (!name || eq(name, "totalcputime") || eq(name, "cputime")) {
int total_sec, total_msec; double total_sec;
# ifdef HAVE_GETRUSAGE # ifdef HAVE_GETRUSAGE
int ret; int ret;
@ -177,76 +169,56 @@ printres(char *name)
if (ret == -1) if (ret == -1)
perror("getrusage(): "); perror("getrusage(): ");
total_sec = (int) (ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec); total_sec = (double) (ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec);
total_msec = (int) (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) / 1000; total_sec += (double) (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) / 1000000;
cpu_elapsed = "CPU"; cpu_elapsed = "CPU";
# else # else
# ifdef HAVE_TIMES # ifdef HAVE_TIMES
struct tms ruse; struct tms ruse;
times(&ruse); times(&ruse);
clock_t x = ruse.tms_utime + ruse.tms_stime; clock_t x = ruse.tms_utime + ruse.tms_stime;
clock_t hz = (clock_t) sysconf(_SC_CLK_TCK); double hz = (double) sysconf(_SC_CLK_TCK);
total_sec = x / hz; total_sec = x / hz;
total_msec = ((x % hz) * 1000) / hz;
cpu_elapsed = "CPU"; cpu_elapsed = "CPU";
# else # else
# ifdef HAVE_FTIME total_sec = seconds(); // Fall back to elapsed time
struct timeb timenow;
ftime(&timenow);
timediff(&timenow, &timebegin, &total_sec, &total_msec);
cpu_elapsed = "elapsed"; cpu_elapsed = "elapsed";
# else
# define NO_RUDATA
# endif
# endif # endif
# endif # endif
if (total_sec >= 0) {
#ifndef NO_RUDATA if (!name || eq(name, "totalcputime")) {
fprintf(cp_out, "Total %s time (seconds) = %.3f \n",
if (total_msec >= 1000) { cpu_elapsed, total_sec);
total_msec -= 1000;
total_sec += 1;
}
if (!name || eq(name, "totalcputime")) {
fprintf(cp_out, "Total %s time (seconds) = %u.%03u \n",
cpu_elapsed, total_sec, total_msec);
}
if (!name || eq(name, "cputime")) {
last_msec = 1000 + total_msec - last_msec;
last_sec = total_sec - last_sec - 1;
if (last_msec >= 1000) {
last_msec -= 1000;
last_sec += 1;
} }
/* do not print it the first time, doubling totalcputime */
if (called)
fprintf(cp_out, "%s time since last call (seconds) = %lu.%03lu \n",
cpu_elapsed, last_sec, last_msec);
last_sec = total_sec; if (!name || eq(name, "cputime")) {
last_msec = total_msec;
called = TRUE; /* do not print it the first time */
} if (called)
fprintf(cp_out, "%s time since last call (seconds) = %.3f \n",
cpu_elapsed, total_sec-last_sec);
last_sec = total_sec;
called = TRUE;
}
#ifdef XSPICE #ifdef XSPICE
/* gtri - add - 12/12/90 - wbk - record cpu time used for ipc */ /* gtri - add - 12/12/90 - wbk - record cpu time used for ipc */
g_ipc.cpu_time = (double) last_msec; g_ipc.cpu_time = last_sec;
g_ipc.cpu_time /= 1000.0; /* gtri - end - 12/12/90 */
g_ipc.cpu_time += (double) last_sec;
/* gtri - end - 12/12/90 */
#endif #endif
yy = TRUE; yy = TRUE;
#else
if (!name || eq(name, "totalcputime")) } else { // total_sec < 0)
fprintf(cp_out, "Total CPU time: ??.??? seconds.\n");
if (!name || eq(name, "cputime")) if (!name || eq(name, "totalcputime"))
fprintf(cp_out, "CPU time since last call: ??.??? seconds.\n"); fprintf(cp_out, "Total CPU time: ??.??? seconds.\n");
yy = TRUE; if (!name || eq(name, "cputime"))
#endif fprintf(cp_out, "CPU time since last call: ??.??? seconds.\n");
yy = TRUE;
}
} }
@ -273,7 +245,7 @@ printres(char *name)
// fprintf(cp_out, "Resident set size = "); // fprintf(cp_out, "Resident set size = ");
// fprintmem(cp_out, mem_ng_act.resident); // fprintmem(cp_out, mem_ng_act.resident);
// fprintf(cp_out, ".\n"); // fprintf(cp_out, ".\n");
fprintf(cp_out, "\n"); fprintf(cp_out, "\n");
fprintf(cp_out, "Shared ngspice pages = "); fprintf(cp_out, "Shared ngspice pages = ");
fprintmem(cp_out, mem_ng_act.shared); fprintmem(cp_out, mem_ng_act.shared);
fprintf(cp_out, ".\n"); fprintf(cp_out, ".\n");

View File

@ -9,8 +9,8 @@
#define MEMWATCH */ #define MEMWATCH */
/* /*
* This file will eventually replace spice.h and lots of other * This file will eventually replace spice.h and lots of other
* files in src/include * files in src/include
*/ */
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
@ -117,15 +117,19 @@
# include <sys/time.h> # include <sys/time.h>
# include <sys/resource.h> # include <sys/resource.h>
# endif # endif
#else #endif
# ifdef HAVE_TIMES
# include <sys/times.h> #ifdef HAVE_TIMES
# include <sys/param.h> # include <sys/times.h>
# else # include <sys/param.h>
# ifdef HAVE_FTIME #endif
# include <sys/timeb.h>
# endif #ifdef HAVE_GETTIMEOFDAY
# endif # include <sys/time.h>
#endif
#ifdef HAVE_FTIME
# include <sys/timeb.h>
#endif #endif
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H

View File

@ -10,32 +10,6 @@ Copyright 1990 Regents of the University of California. All rights reserved.
#include <string.h> #include <string.h>
#include "misc_time.h" #include "misc_time.h"
#ifdef HAVE_LOCALTIME
#include <time.h>
#endif
#ifdef HAVE_GETRUSAGE
# include <sys/types.h>
# include <sys/time.h>
# include <sys/resource.h>
#else
# ifdef HAVE_TIMES
# include <sys/types.h>
# include <sys/times.h>
# include <sys/param.h>
# else
# ifdef HAVE_FTIME
/* default to ftime if we can't get real CPU times */
# include <sys/types.h>
# include <sys/timeb.h>
# endif
# endif
#endif
#ifdef HAVE_FTIME
# include <sys/timeb.h>
#endif
/* Return the date. Return value is static data. */ /* Return the date. Return value is static data. */
@ -66,53 +40,62 @@ datestring(void)
#endif #endif
} }
/* return time interval in seconds and milliseconds */
#ifdef HAVE_FTIME /* Initialize time */
struct timeb timebegin;
void timediff(struct timeb *now, struct timeb *begin, int *sec, int *msec)
{
*msec = (int) now->millitm - (int) begin->millitm;
*sec = (int) now->time - (int) begin->time;
if (*msec < 0) {
*msec += 1000;
(*sec)--;
}
return;
#ifdef HAVE_GETTIMEOFDAY
struct timeval timezero;
void timebegin(void) {
gettimeofday(&timezero, NULL);
} }
#endif #else
#ifdef HAVE_TIMES
clock_t timezero;
void timebegin(void) {
struct tms ruse;
timezero = times(&ruse);
}
/* #else
* How many seconds have elapsed in running time. #ifdef HAVE_FTIME
* This is the routine called in IFseconds struct timeb timezero;
void timebegin(void) {
ftime(&timezero);
}
#endif /* FTIME */
#endif /* TIMES */
#endif /* GETTIMEOFDAY */
/*
* How many seconds have elapsed in running time.
* This is the routine called in IFseconds
*/ */
double double
seconds(void) seconds(void)
{ {
#ifdef HAVE_GETRUSAGE #ifdef HAVE_GETTIMEOFDAY
int ret; struct timeval timenow;
struct rusage ruse; int sec, msec, usec;
gettimeofday(&timenow, NULL);
sec = (int) timenow.tv_sec - (int) timezero.tv_sec;
usec = (int) timenow.tv_usec - (int) timezero.tv_usec;
msec = usec / 1000; // Get rid of extra accuracy
return(sec + (double) msec / 1000.0);
memset(&ruse, 0, sizeof(ruse));
ret = getrusage(RUSAGE_SELF, &ruse);
if(ret == -1) {
perror("getrusage(): ");
return 1;
}
return ((double)ruse.ru_utime.tv_sec + (double) ruse.ru_utime.tv_usec / 1000000.0);
#else #else
#ifdef HAVE_TIMES #ifdef HAVE_TIMES
struct tms ruse;
long long msec;
struct tms tmsbuf; clock_t timenow = times(&ruse);
double hz = (double) sysconf(_SC_CLK_TCK);
times(&tmsbuf); msec = (timenow - timezero) / hz * 1000.0; // Get rid of extra accuracy
return((double) tmsbuf.tms_utime / HZ); return((double) msec / 1000.0);
#else #else
#ifdef HAVE_FTIME #ifdef HAVE_FTIME
@ -120,14 +103,15 @@ seconds(void)
int sec, msec; int sec, msec;
ftime(&timenow); ftime(&timenow);
timediff(&timenow, &timebegin, &sec, &msec);
sec = (int) timenow.time - (int) timezero.time;
msec = (int) timenow.millitm - (int) timezero.millitm;
return(sec + (double) msec / 1000.0); return(sec + (double) msec / 1000.0);
#else /* unknown */ #else /* unknown */
/* don't know how to do this in general. */
return(-1.0); /* Obvious error condition */ return(-1.0); /* Obvious error condition */
#endif /* !FTIME */ #endif /* FTIME */
#endif /* !SYSV */ #endif /* TIMES */
#endif /* !BSD */ #endif /* GETTIMEOFDAY */
} }

View File

@ -8,13 +8,6 @@
char * datestring(void); char * datestring(void);
double seconds(void); double seconds(void);
void timebegin(void);
#ifdef HAVE_FTIME
extern struct timeb timebegin;
void timediff(struct timeb *, struct timeb *, int *, int *);
#endif
#endif #endif