From fc445c2b0a57eeb3b3e262ca1acddff623d0c111 Mon Sep 17 00:00:00 2001 From: caand Date: Tue, 28 Jul 2020 18:01:46 +0200 Subject: [PATCH] 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. --- configure.ac | 10 +-- src/frontend/resource.c | 98 +++++++++++------------------ src/include/ngspice/ngspice.h | 26 ++++---- src/misc/misc_time.c | 112 +++++++++++++++------------------- src/misc/misc_time.h | 9 +-- 5 files changed, 102 insertions(+), 153 deletions(-) diff --git a/configure.ac b/configure.ac index 2419e69f1..328eda940 100644 --- a/configure.ac +++ b/configure.ac @@ -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_STRUCT_TM AC_STRUCT_TIMEZONE -AC_CHECK_FUNCS([localtime]) +AC_CHECK_FUNCS([localtime time]) -AC_CHECK_FUNCS([ftime gettimeofday]) -# Do not use time or getrusage function for CPU time measurement under OpenMP -if test "x$enable_openmp" != xyes; then - AC_CHECK_FUNCS([time getrusage]) -fi -AC_CHECK_FUNCS([utimes]) +AC_CHECK_FUNCS([gettimeofday times ftime], [break]) +AC_CHECK_FUNCS([getrusage times], [break]) AC_CHECK_FUNCS([getrlimit ulimit], [break]) AC_CHECK_FUNCS([endpwent gethostbyname memset select socket strdup strerror strncasecmp strstr strtol]) diff --git a/src/frontend/resource.c b/src/frontend/resource.c index b8013eec9..c77df5061 100644 --- a/src/frontend/resource.c +++ b/src/frontend/resource.c @@ -22,7 +22,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include -#include "../misc/misc_time.h" /* timediff */ +#include "../misc/misc_time.h" /* timebegin */ #ifdef XSPICE /* gtri - add - 12/12/90 - wbk - include ipc stuff */ @@ -81,15 +81,7 @@ init_rlimits(void) void init_time(void) { -#ifdef HAVE_GETRUSAGE -#else -# ifdef HAVE_TIMES -# else -# ifdef HAVE_FTIME - ftime(&timebegin); -# endif -# endif -#endif + timebegin(); } @@ -162,12 +154,12 @@ printres(char *name) #endif bool yy = FALSE; static bool called = FALSE; - static long last_sec = 0, last_msec = 0; + static double last_sec = 0; struct variable *v, *vfree = NULL; char *cpu_elapsed; if (!name || eq(name, "totalcputime") || eq(name, "cputime")) { - int total_sec, total_msec; + double total_sec; # ifdef HAVE_GETRUSAGE int ret; @@ -177,76 +169,56 @@ printres(char *name) if (ret == -1) perror("getrusage(): "); - total_sec = (int) (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_sec + ruse.ru_stime.tv_sec); + total_sec += (double) (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec) / 1000000; cpu_elapsed = "CPU"; # else # ifdef HAVE_TIMES struct tms ruse; times(&ruse); 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_msec = ((x % hz) * 1000) / hz; cpu_elapsed = "CPU"; # else -# ifdef HAVE_FTIME - struct timeb timenow; - ftime(&timenow); - timediff(&timenow, &timebegin, &total_sec, &total_msec); + total_sec = seconds(); // Fall back to elapsed time cpu_elapsed = "elapsed"; -# else -# define NO_RUDATA -# endif # endif # endif + if (total_sec >= 0) { -#ifndef NO_RUDATA - - if (total_msec >= 1000) { - 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; + if (!name || eq(name, "totalcputime")) { + fprintf(cp_out, "Total %s time (seconds) = %.3f \n", + cpu_elapsed, total_sec); } - /* 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; - last_msec = total_msec; - called = TRUE; - } + if (!name || eq(name, "cputime")) { + + /* 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 - /* gtri - add - 12/12/90 - wbk - record cpu time used for ipc */ - g_ipc.cpu_time = (double) last_msec; - g_ipc.cpu_time /= 1000.0; - g_ipc.cpu_time += (double) last_sec; - /* gtri - end - 12/12/90 */ + /* gtri - add - 12/12/90 - wbk - record cpu time used for ipc */ + g_ipc.cpu_time = last_sec; + /* gtri - end - 12/12/90 */ #endif - yy = TRUE; -#else - if (!name || eq(name, "totalcputime")) - fprintf(cp_out, "Total CPU time: ??.??? seconds.\n"); - if (!name || eq(name, "cputime")) - fprintf(cp_out, "CPU time since last call: ??.??? seconds.\n"); - yy = TRUE; -#endif + yy = TRUE; + + } else { // total_sec < 0) + + if (!name || eq(name, "totalcputime")) + fprintf(cp_out, "Total CPU time: ??.??? seconds.\n"); + if (!name || eq(name, "cputime")) + 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 = "); // fprintmem(cp_out, mem_ng_act.resident); // fprintf(cp_out, ".\n"); - fprintf(cp_out, "\n"); + fprintf(cp_out, "\n"); fprintf(cp_out, "Shared ngspice pages = "); fprintmem(cp_out, mem_ng_act.shared); fprintf(cp_out, ".\n"); diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index 0b4f6e710..395ba1104 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -9,8 +9,8 @@ #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 */ #ifndef _GNU_SOURCE @@ -117,15 +117,19 @@ # include # include # endif -#else -# ifdef HAVE_TIMES -# include -# include -# else -# ifdef HAVE_FTIME -# include -# endif -# endif +#endif + +#ifdef HAVE_TIMES +# include +# include +#endif + +#ifdef HAVE_GETTIMEOFDAY +# include +#endif + +#ifdef HAVE_FTIME +# include #endif #ifdef HAVE_UNISTD_H diff --git a/src/misc/misc_time.c b/src/misc/misc_time.c index 415089956..3de58c497 100644 --- a/src/misc/misc_time.c +++ b/src/misc/misc_time.c @@ -10,32 +10,6 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include #include "misc_time.h" -#ifdef HAVE_LOCALTIME -#include -#endif - -#ifdef HAVE_GETRUSAGE -# include -# include -# include -#else -# ifdef HAVE_TIMES -# include -# include -# include -# else -# ifdef HAVE_FTIME -/* default to ftime if we can't get real CPU times */ -# include -# include -# endif -# endif -#endif - -#ifdef HAVE_FTIME -# include -#endif - /* Return the date. Return value is static data. */ @@ -66,53 +40,62 @@ datestring(void) #endif } -/* return time interval in seconds and milliseconds */ -#ifdef HAVE_FTIME - -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; +/* Initialize time */ +#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); +} -/* - * How many seconds have elapsed in running time. - * This is the routine called in IFseconds +#else +#ifdef HAVE_FTIME +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 seconds(void) { -#ifdef HAVE_GETRUSAGE - int ret; - struct rusage ruse; +#ifdef HAVE_GETTIMEOFDAY + struct timeval timenow; + 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 #ifdef HAVE_TIMES + struct tms ruse; + long long msec; - struct tms tmsbuf; - - times(&tmsbuf); - return((double) tmsbuf.tms_utime / HZ); + clock_t timenow = times(&ruse); + double hz = (double) sysconf(_SC_CLK_TCK); + msec = (timenow - timezero) / hz * 1000.0; // Get rid of extra accuracy + return((double) msec / 1000.0); #else #ifdef HAVE_FTIME @@ -120,14 +103,15 @@ seconds(void) int sec, msec; 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); #else /* unknown */ - /* don't know how to do this in general. */ return(-1.0); /* Obvious error condition */ -#endif /* !FTIME */ -#endif /* !SYSV */ -#endif /* !BSD */ +#endif /* FTIME */ +#endif /* TIMES */ +#endif /* GETTIMEOFDAY */ } diff --git a/src/misc/misc_time.h b/src/misc/misc_time.h index 95cc1bcb2..85642d1a8 100644 --- a/src/misc/misc_time.h +++ b/src/misc/misc_time.h @@ -8,13 +8,6 @@ char * datestring(void); double seconds(void); - -#ifdef HAVE_FTIME - -extern struct timeb timebegin; - -void timediff(struct timeb *, struct timeb *, int *, int *); - -#endif +void timebegin(void); #endif