From e0d88085f106c63f21b935fe150c41f1ea923759 Mon Sep 17 00:00:00 2001 From: dwarning Date: Mon, 28 Oct 2024 14:20:45 +0100 Subject: [PATCH] timer functions rework - linux part --- configure.ac | 5 +- src/frontend/resource.c | 61 ++++----------- src/misc/misc_time.c | 162 +++++++++++++--------------------------- src/misc/misc_time.h | 39 ++-------- src/winmain.c | 13 ++-- 5 files changed, 82 insertions(+), 198 deletions(-) diff --git a/configure.ac b/configure.ac index 547b79f4e..a42cd6553 100644 --- a/configure.ac +++ b/configure.ac @@ -908,9 +908,8 @@ AC_STRUCT_TM AC_STRUCT_TIMEZONE AC_CHECK_FUNCS([time localtime]) -AC_CHECK_FUNCS([clock_gettime gettimeofday ftime]) - -# Do not use getrusage function for CPU time measurement under OpenMP +AC_CHECK_FUNCS([queryperformancecounter clock_gettime gettimeofday ftime]) +# Do not use times or getrusage function for CPU time measurement under OpenMP if test "x$enable_openmp" = xno; then AC_CHECK_FUNCS([times getrusage]) fi diff --git a/src/frontend/resource.c b/src/frontend/resource.c index 40b73f91b..a00445c28 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" /* timebegin */ +#include "../misc/misc_time.h" /* timediff */ #ifdef XSPICE /* gtri - add - 12/12/90 - wbk - include ipc stuff */ @@ -77,31 +77,12 @@ init_rlimits(void) ft_ckspace(); } -#if defined HAVE_CLOCK_GETTIME || defined HAVE_GETTIMEOFDAY || defined HAVE_FTIME - PortableTime timebegin; -#endif -#ifdef HAVE_GETRUSAGE - GTimer gtimer; -#endif -#ifdef HAVE_TIMES - TTimer ttimer; -#endif +PerfTimer timer; void init_time(void) { -#if defined HAVE_CLOCK_GETTIME || defined HAVE_GETTIMEOFDAY || defined HAVE_FTIME - get_portable_time(&timebegin); -#else -#ifdef HAVE_GETRUSAGE - start_timer(>imer); -#else -#ifdef HAVE_TIMES - clock_t start_clock; - start_clock = start_timer(&ttimer); -#endif -#endif -#endif + perf_timer_start(&timer); } @@ -181,33 +162,23 @@ printres(char *name) if (!name || eq(name, "totalcputime") || eq(name, "cputime")) { int total_sec, total_msec; -#if defined HAVE_CLOCK_GETTIME || defined HAVE_GETTIMEOFDAY || defined HAVE_FTIME - PortableTime timenow; - get_portable_time(&timenow); - timediff(&timenow, &timebegin, &total_sec, &total_msec); - cpu_elapsed = "elapsed"; -#else -#ifdef HAVE_GETRUSAGE - stop_timer(>imer); +#if defined (USE_OMP) \ + || defined (HAVE_QUERYPERFORMANCECOUNTER) || defined(HAVE_CLOCK_GETTIME) \ + || defined (HAVE_GETTIMEOFDAY) || defined(HAVE_TIMES) \ + || defined (HAVE_GETRUSAGE) || defined(HAVE_FTIME) - total_sec = (int) (gtimer.end.ru_utime.tv_sec + gtimer.start.ru_stime.tv_sec); - total_msec = (int) (gtimer.end.ru_utime.tv_usec + gtimer.start.ru_stime.tv_usec) / 1000; - cpu_elapsed = "CPU"; -#else -#ifdef HAVE_TIMES - clock_t stop_clock = stop_timer(&ttimer); - clock_t user_time = (ttimer.end.tms_utime - ttimer.start.tms_utime); - clock_t system_time = (ttimer.end.tms_stime - ttimer.start.tms_stime); - clock_t x = user_time + system_time; - clock_t hz = (clock_t) sysconf(_SC_CLK_TCK); - total_sec = (int) (x / hz); - total_msec = (int) (((x % hz) * 1000) / hz); + perf_timer_stop(&timer); + perf_timer_elapsed_sec_ms(&timer, &total_sec, &total_msec); + +#if defined (HAVE_TIMES) || defined(HAVE_GETRUSAGE) cpu_elapsed = "CPU"; #else + cpu_elapsed = "elapsed"; +#endif + +# else # define NO_RUDATA -# endif -# endif -# endif +# endif #ifndef NO_RUDATA diff --git a/src/misc/misc_time.c b/src/misc/misc_time.c index 318a8a402..2dcf2dd51 100644 --- a/src/misc/misc_time.c +++ b/src/misc/misc_time.c @@ -10,11 +10,10 @@ Copyright 1990 Regents of the University of California. All rights reserved. #include #include "misc_time.h" -#ifdef HAVE_LOCALTIME -#include +#ifdef USE_OMP +#include #endif - /* Return the date. Return value is static data. */ char * @@ -44,122 +43,65 @@ datestring(void) #endif } -/* return time interval in seconds and milliseconds */ - -#if defined HAVE_CLOCK_GETTIME || defined HAVE_GETTIMEOFDAY || defined HAVE_FTIME - -void timediff(PortableTime *now, PortableTime *begin, int *sec, int *msec) -{ - - *msec = (int) now->milliseconds - (int) begin->milliseconds; - *sec = (int) now->seconds - (int) begin->seconds; - if (*msec < 0) { - *msec += 1000; - (*sec)--; - } - return; - -} - -#ifdef HAVE_CLOCK_GETTIME -void get_portable_time(PortableTime *pt) { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - - pt->seconds = ts.tv_sec; - pt->milliseconds = ts.tv_nsec / 1000000; // Convert nanoseconds to milliseconds -} -#else -#ifdef HAVE_GETTIMEOFDAY -void get_portable_time(PortableTime *pt) { - struct timeval tv; - gettimeofday(&tv, NULL); - pt->seconds = tv.tv_sec; - pt->milliseconds = tv.tv_usec / 1000; // Convert microseconds to milliseconds -} -#else -#ifdef HAVE_FTIME -void get_portable_time(PortableTime *pt) { - struct timeb timenow; - ftime(&timenow); - pt->seconds = (long int)timenow.time; - pt->milliseconds = timenow.millitm; -} -#endif -#endif -#endif - -#endif - -/* - * How many seconds have elapsed in running time. - * This is the routine called in IFseconds where start / stop is handled - * and we don't need calculate timediff here. +/* + * How many seconds have elapsed in running time. + * This is the routine called in IFseconds */ double seconds(void) { -#if defined HAVE_CLOCK_GETTIME || defined HAVE_GETTIMEOFDAY || defined HAVE_FTIME - PortableTime timenow; - - get_portable_time(&timenow); - return((double) timenow.seconds + (double) timenow.milliseconds / 1000.0); +#ifdef USE_OMP + // Usage of OpenMP time function + return omp_get_wtime(); +#elif defined(HAVE_QUERYPERFORMANCECOUNTER) + // Windows (MSC and mingw) specific implementation + LARGE_INTEGER frequency, counter; + QueryPerformanceFrequency(&frequency); + QueryPerformanceCounter(&counter); + return (double)counter.QuadPart / frequency.QuadPart; +#elif defined(HAVE_CLOCK_GETTIME) + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec + ts.tv_nsec / 1e9; +#elif defined(HAVE_GETTIMEOFDAY) + // Usage of gettimeofday + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1e6; +#elif defined(HAVE_TIMES) + // Usage of times + struct tms t; + clock_t ticks = times(&t); + return (double)ticks / sysconf(_SC_CLK_TCK); +#elif defined(HAVE_GETRUSAGE) + // Usage of getrusage + struct rusage usage; + getrusage(RUSAGE_SELF, &usage); + return usage.ru_utime.tv_sec + usage.ru_utime.tv_usec / 1e6; +#elif defined(HAVE_FTIME) + // Usage of ftime + struct timeb tb; + ftime(&tb); + return tb.time + tb.millitm / 1000.0; #else -#ifdef HAVE_GETRUSAGE - int ret; - struct rusage ruse; - - 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 tmsbuf; - - times(&tmsbuf); - return((double) tmsbuf.tms_utime / (clock_t) sysconf(_SC_CLK_TCK)); - -#else /* unknown */ - - return(-1.0); /* Obvious error condition */ - -#endif /* GETRUSAGE */ -#endif /* TIMES */ -#endif /* CLOCK_GETTIME || GETTIMEOFDAY || FTIME */ + error_no_timer_function_available; +#endif } -#ifdef HAVE_GETRUSAGE -void start_timer(GTimer *timer) { - int ret; - ret = getrusage(RUSAGE_SELF, &timer->start); - if(ret == -1) { - perror("getrusage(): "); - } +void perf_timer_start(PerfTimer *timer) +{ + timer->start = seconds(); } -void stop_timer(GTimer *timer) { - int ret; - ret = getrusage(RUSAGE_SELF, &timer->end); - if(ret == -1) { - perror("getrusage(): "); - } -} -#endif /* GETRUSAGE */ -#ifdef HAVE_TIMES -clock_t start_timer(TTimer *timer) { - clock_t start_clock; - start_clock = times(&timer->start); - return start_clock; +void perf_timer_stop(PerfTimer *timer) +{ + timer->end = seconds(); } -clock_t stop_timer(TTimer *timer) { - clock_t stop_clock; - stop_clock = times(&timer->end); - return stop_clock; + +void perf_timer_elapsed_sec_ms(const PerfTimer *timer, int *seconds, int *milliseconds) +{ + double elapsed = timer->end - timer->start; + *seconds = (int)elapsed; + *milliseconds = (int)((elapsed - *seconds) * 1000.0); } -#endif /* TIMES */ diff --git a/src/misc/misc_time.h b/src/misc/misc_time.h index 59088b7b9..a9fb85029 100644 --- a/src/misc/misc_time.h +++ b/src/misc/misc_time.h @@ -9,40 +9,13 @@ char * datestring(void); double seconds(void); -#if defined HAVE_CLOCK_GETTIME || defined HAVE_GETTIMEOFDAY || defined HAVE_FTIME - typedef struct { - long seconds; - long milliseconds; -} PortableTime; + double start; + double end; +} PerfTimer; -void get_portable_time(PortableTime *); -void timediff(PortableTime *, PortableTime *, int *, int *); - -#endif - -#ifdef HAVE_GETRUSAGE - -typedef struct { - struct rusage start; - struct rusage end; -} GTimer; - -void start_timer(GTimer *); -void stop_timer(GTimer *); - -#endif - -#ifdef HAVE_TIMES - -typedef struct { - struct tms start; - struct tms end; -} TTimer; - -clock_t start_timer(TTimer *); -clock_t stop_timer(TTimer *); - -#endif +void perf_timer_start(PerfTimer *); +void perf_timer_stop(PerfTimer *); +void perf_timer_elapsed_sec_ms(const PerfTimer *, int *, int *); #endif diff --git a/src/winmain.c b/src/winmain.c index 92dd22d64..be2ed01b5 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -38,7 +38,7 @@ #include "hist_info.h" /* history management */ #include "ngspice/bool.h" /* bool defined as unsigned char */ -#include "misc/misc_time.h" /* timediff */ +#include "misc/misc_time.h" /* timer functions and structure */ #include "ngspice/memory.h" /* TMALLOC */ #include "winmain.h" @@ -220,8 +220,7 @@ SetAnalyse(char *Analyse, /* in: analysis type */ static int OldPercent = -2; /* Previous progress value */ static char OldAn[128]; /* Previous analysis type */ char s[128], t[128]; /* outputs to analysis window and task bar */ - static PortableTime timebefore; /* previous time stamp */ - PortableTime timenow; /* actual time stamp */ + PortableTime timer; /* previous time stamp and actual time stamp */ int diffsec, diffmillisec; /* differences actual minus prev. time stamp */ WaitForIdle(); @@ -232,8 +231,8 @@ SetAnalyse(char *Analyse, /* in: analysis type */ return; /* get actual time */ - get_portable_time(&timenow); - timediff(&timenow, &timebefore, &diffsec, &diffmillisec); + perf_timer_stop(&timer); + perf_timer_elapsed_sec_ms(&timer, &diffsec, &diffmillisec); OldPercent = DecaPercent; /* output only into hwAnalyse window and if time elapsed is larger than @@ -255,8 +254,8 @@ SetAnalyse(char *Analyse, /* in: analysis type */ sprintf(s, " %s: %3.1f%%", Analyse, (double)DecaPercent/10.); sprintf(t, "%s %3.1f%%", PACKAGE_STRING, (double)DecaPercent/10.); } - timebefore.milliseconds = timenow.milliseconds; - timebefore.seconds = timenow.seconds; +// timebefore.milliseconds = timenow.milliseconds; +// timebefore.seconds = timenow.seconds; /* info when previous analysis period has finished */ if (strcmp(OldAn, Analyse)) { if ((ft_nginfo || ft_ngdebug) && (strcmp(OldAn, "")))