1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * All rights reserved.                                                      *
4  *                                                                           *
5  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6  * terms governing use, modification, and redistribution, is contained in    *
7  * the COPYING file, which can be found at the root of the source code       *
8  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
9  * If you do not have access to either file, you may request a copy from     *
10  * help@hdfgroup.org.                                                        *
11  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12 /* changes:
13  * rename pio_timer.c as io_timer.c;
14  * Removed pio_perf.h so that it is not dependant on it;
15  * Removed set_timer_type() and get_timer_type() since no one calls them;
16  * Merged sio_timer.c into io_timer.c;
17  */
18 
19 /*
20  * Purpose:
21  *
22  * This is a module of useful timing functions for performance testing.
23  */
24 
25 #include "H5private.h"
26 #include "hdf5.h"
27 
28 #include "io_timer.h"
29 
30 /*
31  * The number to divide the tv_usec field with to get a nice decimal to add to
32  * the number of seconds.
33  */
34 #define MICROSECOND     1000000.0F
35 
36 /* global variables */
37 io_time_t   *timer_g;            /* timer: global for stub functions     */
38 
39 /*
40  * Function:  sub_time
41  * Purpose:   Struct two time values, and return the difference, in microseconds
42  *
43  *         Note that the function assumes that a > b
44  * Programmer: Leon Arber, 1/27/06
45  */
sub_time(struct timeval * a,struct timeval * b)46 static double sub_time(struct timeval* a, struct timeval* b)
47 {
48     return (((double)a->tv_sec +
49      ((double)a->tv_usec) / (double)MICROSECOND) -
50   ((double)b->tv_sec +
51    ((double)b->tv_usec) / (double)MICROSECOND));
52 }
53 
54 
55 /*
56  * Function:    io_time_new
57  * Purpose:     Build us a brand, spankin', new performance time object.
58  *              The object is a black box to the user. They just tell us
59  *              what type of timer they want (MPI_CLOCK for MPI_Wtime or
60  *              SYS_CLOCK for system time).
61  * Return:      Pointer to io_time object
62  * Programmer:  Bill Wendling, 01. October 2001
63  * Modifications:
64  */
65 io_time_t *
io_time_new(clock_type type)66 io_time_new(clock_type type)
67 {
68     io_time_t *pt = (io_time_t *)HDcalloc(1, sizeof(struct io_time_t));
69 
70     /* set global timer variable */
71     timer_g = pt;
72 
73     pt->type = type;
74     return pt;
75 }
76 
77 /*
78  * Function:    io_time_destroy
79  * Purpose:     Remove the memory allocated for the io_time object. Only
80  *              need to call on a pointer allocated with the ``io_time_new''
81  *              function.
82  * Return:      Nothing
83  * Programmer:  Bill Wendling, 01. October 2001
84  * Modifications:
85  */
86 void
io_time_destroy(io_time_t * pt)87 io_time_destroy(io_time_t *pt)
88 {
89     HDfree(pt);
90     /* reset the global timer pointer too. */
91     timer_g = NULL;
92 }
93 
94 #if 0
95 /* no one is calling set_timer_type or get_timer_type ???*/
96 /*
97  * Function:    set_timer_type
98  * Purpose:     Set the type of the timer to either MPI_CLOCK or SYS_CLOCK.
99  *              This really only needs to be called if you didn't construct a
100  *              timer with the pio_timer_new function (shame!).
101  * Return:      Nothing
102  * Programmer:  Bill Wendling, 04. October 2001
103  * Modifications:
104  */
105 void
106 set_timer_type(io_time_t *pt, clock_type type)
107 {
108     pt->type = type;
109 }
110 
111 /*
112  * Function:    get_timer_type
113  * Purpose:     Get the type of the timer.
114  * Return:      MPI_CLOCK or SYS_CLOCK.
115  * Programmer:  Bill Wendling, 04. October 2001
116  * Modifications:
117  */
118 clock_type
119 get_timer_type(io_time_t *pt)
120 {
121     return pt->type;
122 }
123 #endif
124 
125 /*
126  * Function:    set_time
127  * Purpose:     Set the time in a ``io_time_t'' object.
128  * Return:      Pointer to the passed in ``io_time_t'' object if SUCCEED; Null otherwise.
129  * Programmer:  Bill Wendling, 01. October 2001
130  * Modifications:
131  */
132 io_time_t *
set_time(io_time_t * pt,timer_type t,int start_stop)133 set_time(io_time_t *pt, timer_type t, int start_stop)
134 {
135     /* sanity check */
136     assert(pt);
137 
138     switch(pt->type){
139 #ifdef H5_HAVE_PARALLEL
140     case MPI_CLOCK:
141 	if (start_stop == TSTART) {
142 	    pt->mpi_timer[t] = MPI_Wtime();
143 
144 	    /* When we start the timer for HDF5_FINE_WRITE_FIXED_DIMS or HDF5_FINE_READ_FIXED_DIMS
145 	     * we compute the time it took to only open the file */
146 	    if(t == HDF5_FINE_WRITE_FIXED_DIMS)
147 		pt->total_time[HDF5_FILE_WRITE_OPEN] += pt->mpi_timer[t] - pt->mpi_timer[HDF5_GROSS_WRITE_FIXED_DIMS];
148 	    else if(t == HDF5_FINE_READ_FIXED_DIMS)
149 		pt->total_time[HDF5_FILE_READ_OPEN] += pt->mpi_timer[t] - pt->mpi_timer[HDF5_GROSS_READ_FIXED_DIMS];
150 
151 	} else {
152 	    pt->total_time[t] += MPI_Wtime() - pt->mpi_timer[t];
153 	    pt->mpi_timer[t] = MPI_Wtime();
154 
155 	    /* When we stop the timer for HDF5_GROSS_WRITE_FIXED_DIMS or HDF5_GROSS_READ_FIXED_DIMS
156 	     * we compute the time it took to close the file after the last read/write finished */
157 	    if(t == HDF5_GROSS_WRITE_FIXED_DIMS)
158 		pt->total_time[HDF5_FILE_WRITE_CLOSE] += pt->mpi_timer[t] - pt->mpi_timer[HDF5_FINE_WRITE_FIXED_DIMS];
159 	    else if(t == HDF5_GROSS_READ_FIXED_DIMS)
160 		pt->total_time[HDF5_FILE_READ_CLOSE] += pt->mpi_timer[t] - pt->mpi_timer[HDF5_FINE_READ_FIXED_DIMS];
161 	}
162 	break;
163 #endif /* H5_HAVE_PARALLEL */
164     case SYS_CLOCK:
165             if (start_stop == TSTART) {
166                 HDgettimeofday(&pt->sys_timer[t], NULL);
167 
168 		/* When we start the timer for HDF5_FINE_WRITE_FIXED_DIMS or HDF5_FINE_READ_FIXED_DIMS
169 		 * we compute the time it took to only open the file */
170 		if(t == HDF5_FINE_WRITE_FIXED_DIMS)
171 		    pt->total_time[HDF5_FILE_WRITE_OPEN] += sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_GROSS_WRITE_FIXED_DIMS]));
172 		else if(t == HDF5_FINE_READ_FIXED_DIMS)
173 		    pt->total_time[HDF5_FILE_READ_OPEN] += sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_GROSS_READ_FIXED_DIMS]));
174 
175 
176             } else {
177                 struct timeval sys_t;
178 
179                 HDgettimeofday(&sys_t, NULL);
180                 pt->total_time[t] += sub_time(&sys_t, &(pt->sys_timer[t]));
181 
182 		/* When we stop the timer for HDF5_GROSS_WRITE_FIXED_DIMS or HDF5_GROSS_READ_FIXED_DIMS
183 		 * we compute the time it took to close the file after the last read/write finished */
184 		if(t == HDF5_GROSS_WRITE_FIXED_DIMS)
185 		    pt->total_time[HDF5_FILE_WRITE_CLOSE] += sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_FINE_WRITE_FIXED_DIMS]));
186 		else if(t == HDF5_GROSS_READ_FIXED_DIMS)
187 		    pt->total_time[HDF5_FILE_READ_CLOSE] += sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_FINE_READ_FIXED_DIMS]));
188 
189             }
190 	break;
191 
192     default:
193 	    HDfprintf(stderr, "Unknown time clock type (%d)\n", pt->type);
194 	    return NULL;
195     } /* end switch */
196 
197 #if 0
198     /* this does not belong here. Need fix in h5perf code when set_time() is called. -AKC- */
199     debug_start_stop_time(pt, t, start_stop);
200 #endif
201 
202     return pt;
203 }
204 
205 /*
206  * Function:    get_time
207  * Purpose:     Get the time from a ``io_time_t'' object.
208  * Return:      The number of seconds as a DOUBLE.
209  * Programmer:  Bill Wendling, 01. October 2001
210  * Modifications:
211  */
212 double
get_time(io_time_t * pt,timer_type t)213 get_time(io_time_t *pt, timer_type t)
214 {
215     return pt->total_time[t];
216 }
217 
218 #if 0
219 /* standalone is not working yet. Need fix later. -AKC- */
220 #ifdef STANDALONE
221 #include "pio_standalone.c"
222 #endif
223 #endif
224