File: timer_utils.c

package info (click to toggle)
netcdf-parallel 1%3A4.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 113,164 kB
  • sloc: ansic: 267,893; sh: 12,869; cpp: 5,822; yacc: 2,613; makefile: 1,813; lex: 1,216; xml: 173; awk: 2
file content (170 lines) | stat: -rw-r--r-- 4,183 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*********************************************************************
 *   Copyright 2020, UCAR/Unidata
 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
 *********************************************************************/

#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#ifdef HAVE_TIME_H
#include <time.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef _WIN32
#include <windows.h>
#endif

#include "timer_utils.h"

#undef DEBUG

static int NCT_initialized = 0;

#ifdef _WIN32
LARGE_INTEGER frequency;
LARGE_INTEGER starttime;

void
NCT_inittimer(void)
{
    if(NCT_initialized) return;
#ifdef DEBUG
    fprintf(stderr,"timer mechanism: QueryPerformanceCounter\n");
#endif
    LARGE_INTEGER li;
    (void)QueryPerformanceFrequency(&frequency);
    QueryPerformanceCounter(&starttime);
#ifdef DEBUG
fprintf(stderr,"frequency=%lld starttime=%lld\n",frequency.QuadPart,starttime.QuadPart);
#endif
    NCT_initialized = 1;
}
#else
void
NCT_inittimer(void)
{
    if(NCT_initialized) return;
#ifdef DEBUG
#if defined HAVE_CLOCK_GETTIME
    fprintf(stderr,"timer mechanism: clock_gettime\n");
#elif defined HAVE_GETTIMEOFDAY 
    fprintf(stderr,"timer mechanism: gettimeofday\n");
#elif defined HAVE_GETRUSAGE
    fprintf(stderr,"timer mechanism: getrusage\n");
#else
    fprintf(stderr,"timer mechanism: Unknown\n");
#endif
#endif /*DEBUG*/
    NCT_initialized = 1;
}
#endif

void
NCT_marktime(Nanotime* nt)
{
#ifdef _WIN32
    LARGE_INTEGER endtime;
    QueryPerformanceCounter(&endtime);
    nt->tv_sec = endtime.QuadPart / 1000000000;
    nt->tv_nsec = endtime.QuadPart % 1000000000;
#ifdef DEBUG
fprintf(stderr,"endtime=%lld\n",endtime.QuadPart);
#endif
#endif

#ifndef _WIN32
/* Pick one */
#ifdef HAVE_CLOCK_GETTIME
    clockid_t clk_id = CLOCK_MONOTONIC;
    struct timespec t;
    clock_gettime(clk_id,&t);
    nt->tv_sec = (long long)t.tv_sec;
    nt->tv_nsec = (long long)t.tv_nsec;
#elif defined HAVE_GETTIMEOFDAY
    struct timeval tp;
    gettimeofday(&tp, NULL);
    nt->tv_sec = (long long)tp.tv_sec;
    nt->tv_nsec = 1000*(long long)tp.tv_usec;
# elif defined HAVE_GETRUSAGE
    struct rusage ru;
    getrusage(RUSAGE_SELF, &ru);
    nt->tv_sec = (long long)(ru.ru_utime.tv_sec + ru.ru_stime.tv_sec);
    nt->tv_nsec = (long long)(1000*(ru.ru_utime.tv_usec + ru.ru_stime.tv_usec));
#endif
#endif
}

void
NCT_elapsedtime(Nanotime* nt0, Nanotime* nt1, Nanotime* delta)
{
    long long nsec[2];
    long long deltansec;
    
    nsec[0] = nt0->tv_nsec+(1000000000 * nt0->tv_sec);
    nsec[1] = nt1->tv_nsec+(1000000000 * nt1->tv_sec);

    deltansec = nsec[1] - nsec[0];
    delta->tv_nsec = deltansec % 1000000000;
    delta->tv_sec = deltansec / 1000000000;
#ifdef DEBUG
fprintf(stderr,"delta=(%lld,%lld)\n",delta->tv_sec,delta->tv_nsec);
#endif
}

int
NCT_reporttime(unsigned nelems, Nanotime* times, struct TimeRange range, const char* tag)
{
    Nanotime delta;
    long long nsec,avg;
    double dnsec,dsec,davg;
    
    NCT_elapsedtime(&times[0],&times[1],&delta);
    nsec = NCT_nanoseconds(delta);
    avg = nsec / nelems;
#ifdef DEBUG
fprintf(stderr,"nsec=%lld avg=%lld\n",nsec,avg);
#endif
    dnsec = (double)nsec;
    dsec = dnsec / 1000000000.0;
#ifdef DEBUG
fprintf(stderr,"dsec=%g dnsec=%g\n",dsec,dnsec);
#endif
    davg = (dnsec/nelems);
    fprintf(stderr,"\t%s:\t%8.6lf sec",tag,dsec);
    fprintf(stderr," avg=%5.2lf nsec\n",davg);
#ifdef DEBUG
     fprintf(stderr,"range: min=%lld max=%lld\n",range.min,range.max);
#endif
    if(!NCT_rangetest(avg,range)) {
        fprintf(stderr,"*** WARNING: unexpectedly large timing values%s\n",tag);
    }
    return 1;
}

long long
NCT_nanoseconds(Nanotime time)
{
    return (time.tv_sec * 1000000000) + time.tv_nsec;
}

/* Provide a time range tester */
int
NCT_rangetest(long long nsec, struct TimeRange range)
{
    if(nsec < range.min) {
	fprintf(stderr,"range: time=%lld  < min=%lld\n",nsec,range.min);
	return 0;
    }
    if(nsec > range.max) {
	fprintf(stderr,"range: time=%lld  > max=%lld\n",nsec,range.max);
	return 0;
    }
    return 1;
}