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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* changes:
* rename pio_timer.c as io_timer.c;
* Removed pio_perf.h so that it is not dependent on it;
* Removed set_timer_type() and get_timer_type() since no one calls them;
* Merged sio_timer.c into io_timer.c;
*/
/*
* Purpose:
*
* This is a module of useful timing functions for performance testing.
*/
#include "H5private.h"
#include "io_timer.h"
/*
* The number to divide the tv_usec field with to get a nice decimal to add to
* the number of seconds.
*/
#define MICROSECOND 1000000.0F
/* global variables */
static io_time_t *timer_g; /* timer: global for stub functions */
/*
* Function: sub_time
* Purpose: Struct two time values, and return the difference, in microseconds
*
* Note that the function assumes that a > b
*/
static double
sub_time(struct timeval *a, struct timeval *b)
{
return (((double)a->tv_sec + ((double)a->tv_usec) / (double)MICROSECOND) -
((double)b->tv_sec + ((double)b->tv_usec) / (double)MICROSECOND));
}
/*
* Function: io_time_new
* Purpose: Build us a brand, spankin', new performance time object.
* The object is a black box to the user. They just tell us
* what type of timer they want (MPI_CLOCK for MPI_Wtime or
* SYS_CLOCK for system time).
* Return: Pointer to io_time object
*/
io_time_t *
io_time_new(clock_type type)
{
io_time_t *pt = (io_time_t *)calloc(1, sizeof(struct io_time_t));
/* set global timer variable */
timer_g = pt;
pt->type = type;
return pt;
}
/*
* Function: io_time_destroy
* Purpose: Remove the memory allocated for the io_time object. Only
* need to call on a pointer allocated with the ``io_time_new''
* function.
* Return: Nothing
*/
void
io_time_destroy(io_time_t *pt)
{
free(pt);
/* reset the global timer pointer too. */
timer_g = NULL;
}
#if 0
/* no one is calling set_timer_type or get_timer_type ???*/
/*
* Function: set_timer_type
* Purpose: Set the type of the timer to either MPI_CLOCK or SYS_CLOCK.
* This really only needs to be called if you didn't construct a
* timer with the pio_timer_new function (shame!).
* Return: Nothing
*/
void
set_timer_type(io_time_t *pt, clock_type type)
{
pt->type = type;
}
/*
* Function: get_timer_type
* Purpose: Get the type of the timer.
* Return: MPI_CLOCK or SYS_CLOCK.
*/
clock_type
get_timer_type(io_time_t *pt)
{
return pt->type;
}
#endif
/*
* Function: io_time_set
* Purpose: Set the time in a ``io_time_t'' object.
* Return: Pointer to the passed in ``io_time_t'' object if SUCCEED; Null otherwise.
*/
io_time_t *
io_time_set(io_time_t *pt, timer_type t, int start_stop)
{
/* sanity check */
assert(pt);
switch (pt->type) {
#ifdef H5_HAVE_PARALLEL
case MPI_CLOCK:
if (start_stop == TSTART) {
pt->mpi_timer[t] = MPI_Wtime();
/* When we start the timer for HDF5_FINE_WRITE_FIXED_DIMS or HDF5_FINE_READ_FIXED_DIMS
* we compute the time it took to only open the file */
if (t == HDF5_FINE_WRITE_FIXED_DIMS)
pt->total_time[HDF5_FILE_WRITE_OPEN] +=
pt->mpi_timer[t] - pt->mpi_timer[HDF5_GROSS_WRITE_FIXED_DIMS];
else if (t == HDF5_FINE_READ_FIXED_DIMS)
pt->total_time[HDF5_FILE_READ_OPEN] +=
pt->mpi_timer[t] - pt->mpi_timer[HDF5_GROSS_READ_FIXED_DIMS];
}
else {
pt->total_time[t] += MPI_Wtime() - pt->mpi_timer[t];
pt->mpi_timer[t] = MPI_Wtime();
/* When we stop the timer for HDF5_GROSS_WRITE_FIXED_DIMS or HDF5_GROSS_READ_FIXED_DIMS
* we compute the time it took to close the file after the last read/write finished */
if (t == HDF5_GROSS_WRITE_FIXED_DIMS)
pt->total_time[HDF5_FILE_WRITE_CLOSE] +=
pt->mpi_timer[t] - pt->mpi_timer[HDF5_FINE_WRITE_FIXED_DIMS];
else if (t == HDF5_GROSS_READ_FIXED_DIMS)
pt->total_time[HDF5_FILE_READ_CLOSE] +=
pt->mpi_timer[t] - pt->mpi_timer[HDF5_FINE_READ_FIXED_DIMS];
}
break;
#else
case MPI_CLOCK:
fprintf(stderr, "MPI clock set in serial library\n");
return NULL;
#endif /* H5_HAVE_PARALLEL */
case SYS_CLOCK:
if (start_stop == TSTART) {
HDgettimeofday(&pt->sys_timer[t], NULL);
/* When we start the timer for HDF5_FINE_WRITE_FIXED_DIMS or HDF5_FINE_READ_FIXED_DIMS
* we compute the time it took to only open the file */
if (t == HDF5_FINE_WRITE_FIXED_DIMS)
pt->total_time[HDF5_FILE_WRITE_OPEN] +=
sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_GROSS_WRITE_FIXED_DIMS]));
else if (t == HDF5_FINE_READ_FIXED_DIMS)
pt->total_time[HDF5_FILE_READ_OPEN] +=
sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_GROSS_READ_FIXED_DIMS]));
}
else {
struct timeval sys_t;
HDgettimeofday(&sys_t, NULL);
pt->total_time[t] += sub_time(&sys_t, &(pt->sys_timer[t]));
/* When we stop the timer for HDF5_GROSS_WRITE_FIXED_DIMS or HDF5_GROSS_READ_FIXED_DIMS
* we compute the time it took to close the file after the last read/write finished */
if (t == HDF5_GROSS_WRITE_FIXED_DIMS)
pt->total_time[HDF5_FILE_WRITE_CLOSE] +=
sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_FINE_WRITE_FIXED_DIMS]));
else if (t == HDF5_GROSS_READ_FIXED_DIMS)
pt->total_time[HDF5_FILE_READ_CLOSE] +=
sub_time(&(pt->sys_timer[t]), &(pt->sys_timer[HDF5_FINE_READ_FIXED_DIMS]));
}
break;
default:
fprintf(stderr, "Unknown time clock type (%d)\n", pt->type);
return NULL;
} /* end switch */
#if 0
/* this does not belong here. Need fix in h5perf code when set_time() is called. -AKC- */
debug_start_stop_time(pt, t, start_stop);
#endif
return pt;
}
/*
* Function: io_time_get
* Purpose: Get the time from a ``io_time_t'' object.
* Return: The number of seconds as a DOUBLE.
*/
H5_ATTR_PURE double
io_time_get(io_time_t *pt, timer_type t)
{
/* sanity check */
assert(pt);
return pt->total_time[t];
}
|