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