Skip to content

Commit cb3e03d

Browse files
authored
Merge pull request #9798 from jsquyres/pr/opal-clock-gettime
RFC: opal_clock_gettime() and opal_clock_getres()
2 parents 65cf76e + e72b4e6 commit cb3e03d

File tree

5 files changed

+142
-66
lines changed

5 files changed

+142
-66
lines changed

configure.ac

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# University of Stuttgart. All rights reserved.
1111
# Copyright (c) 2004-2005 The Regents of the University of California.
1212
# All rights reserved.
13-
# Copyright (c) 2006-2021 Cisco Systems, Inc. All rights reserved
13+
# Copyright (c) 2006-2022 Cisco Systems, Inc. All rights reserved
1414
# Copyright (c) 2006-2008 Sun Microsystems, Inc. All rights reserved.
1515
# Copyright (c) 2006-2017 Los Alamos National Security, LLC. All rights
1616
# reserved.
@@ -694,7 +694,7 @@ AC_CHECK_HEADERS([alloca.h aio.h arpa/inet.h dirent.h \
694694
sys/fcntl.h sys/ipc.h sys/shm.h \
695695
sys/ioctl.h sys/mman.h sys/param.h sys/queue.h \
696696
sys/resource.h sys/select.h sys/socket.h sys/sockio.h \
697-
sys/stat.h sys/statfs.h sys/statvfs.h sys/time.h sys/tree.h \
697+
sys/stat.h sys/statfs.h sys/statvfs.h time.h sys/time.h sys/tree.h \
698698
sys/types.h sys/uio.h sys/un.h net/uio.h sys/utsname.h sys/vfs.h sys/wait.h syslog.h \
699699
termios.h ulimit.h unistd.h util.h utmp.h malloc.h \
700700
ifaddrs.h crt_externs.h regex.h mntent.h paths.h \
@@ -883,6 +883,15 @@ AC_INCLUDES_DEFAULT
883883
#endif
884884
])
885885

886+
AC_CHECK_MEMBERS([struct timespec.tv_nsec],
887+
[], [], [AC_INCLUDES_DEFAULT
888+
#ifdef HAVE_TIME_H
889+
#include <time.h>
890+
#endif
891+
#ifdef HAVE_SYS_TIME_H
892+
#include <sys/time.h>
893+
#endif])
894+
886895
#
887896
# Find corresponding types for MPI_Aint, MPI_Count, and MPI_Offset.
888897
# And if relevant, find the corresponding MPI_ADDRESS_KIND,

ompi/mpi/c/wtick.c

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* University of Stuttgart. All rights reserved.
1010
* Copyright (c) 2004-2005 The Regents of the University of California.
1111
* All rights reserved.
12-
* Copyright (c) 2007-2014 Cisco Systems, Inc. All rights reserved.
12+
* Copyright (c) 2007-2022 Cisco Systems, Inc. All rights reserved
1313
* Copyright (c) 2015-2016 Research Organization for Information Science
1414
* and Technology (RIST). All rights reserved.
1515
* Copyright (c) 2017 IBM Corporation. All rights reserved.
@@ -31,10 +31,11 @@
3131
#include <time.h>
3232
#endif
3333

34-
#include MCA_timer_IMPLEMENTATION_HEADER
3534
#include "ompi/mpi/c/bindings.h"
3635
#include "ompi/runtime/mpiruntime.h"
3736

37+
#include "opal/util/clock_gettime.h"
38+
3839
#if OMPI_BUILD_MPI_PROFILING
3940
#if OPAL_HAVE_WEAK_SYMBOLS
4041
#pragma weak MPI_Wtick = PMPI_Wtick
@@ -44,38 +45,15 @@
4445

4546
double MPI_Wtick(void)
4647
{
47-
/*
48-
* See https://github.com/open-mpi/ompi/issues/3003
49-
* to get an idea what's going on here.
50-
*/
51-
#if 0
52-
#if OPAL_TIMER_CYCLE_NATIVE
53-
{
54-
opal_timer_t freq = opal_timer_base_get_freq();
55-
if (0 == freq) {
56-
/* That should never happen, but if it does, return a bogus value
57-
* rather than crashing with a division by zero */
58-
return (double)0.0;
59-
}
60-
return (double)1.0 / (double)freq;
61-
}
62-
#elif OPAL_TIMER_USEC_NATIVE
63-
return 0.000001;
64-
#endif
65-
#else
66-
#if defined(__linux__) && OPAL_HAVE_CLOCK_GETTIME
48+
// We intentionally don't use the OPAL timer framework here. See
49+
// https://github.com/open-mpi/ompi/issues/3003 for more details.
6750
struct timespec spec;
6851
double wtick = 0.0;
69-
if (0 == clock_getres(CLOCK_MONOTONIC, &spec)){
52+
if (0 == opal_clock_getres(&spec)){
7053
wtick = spec.tv_sec + spec.tv_nsec * 1.0e-09;
7154
} else {
7255
/* guess */
7356
wtick = 1.0e-09;
7457
}
7558
return wtick;
76-
#else
77-
/* Otherwise, we already return usec precision. */
78-
return 0.000001;
79-
#endif
80-
#endif
8159
}

ompi/mpi/c/wtime.c

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* University of Stuttgart. All rights reserved.
1010
* Copyright (c) 2004-2005 The Regents of the University of California.
1111
* All rights reserved.
12-
* Copyright (c) 2006-2014 Cisco Systems, Inc. All rights reserved.
12+
* Copyright (c) 2006-2022 Cisco Systems, Inc. All rights reserved
1313
* Copyright (c) 2015 Research Organization for Information Science
1414
* and Technology (RIST). All rights reserved.
1515
* Copyright (c) 2017 IBM Corporation. All rights reserved.
@@ -31,11 +31,12 @@
3131
#include <time.h>
3232
#endif /* HAVE_TIME_H */
3333

34-
#include MCA_timer_IMPLEMENTATION_HEADER
3534
#include "ompi/mpi/c/bindings.h"
3635
#include "ompi/runtime/mpiruntime.h"
3736
#include "ompi/runtime/ompi_spc.h"
3837

38+
#include "opal/util/clock_gettime.h"
39+
3940
#if OMPI_BUILD_MPI_PROFILING
4041
#if OPAL_HAVE_WEAK_SYMBOLS
4142
#pragma weak MPI_Wtime = PMPI_Wtime
@@ -46,17 +47,9 @@
4647
* and accuracy of the user visible timer.
4748
* More info: https://github.com/mpi-forum/mpi-issues/issues/77#issuecomment-369663119
4849
*/
49-
#if defined(__linux__) && OPAL_HAVE_CLOCK_GETTIME
5050
struct timespec ompi_wtime_time_origin = {.tv_sec = 0};
51-
#else
52-
struct timeval ompi_wtime_time_origin = {.tv_sec = 0};
53-
#endif
5451
#else /* OMPI_BUILD_MPI_PROFILING */
55-
#if defined(__linux__) && OPAL_HAVE_CLOCK_GETTIME
5652
extern struct timespec ompi_wtime_time_origin;
57-
#else
58-
extern struct timeval ompi_wtime_time_origin;
59-
#endif
6053
#endif
6154

6255
double MPI_Wtime(void)
@@ -65,36 +58,15 @@ double MPI_Wtime(void)
6558

6659
SPC_RECORD(OMPI_SPC_WTIME, 1);
6760

68-
/*
69-
* See https://github.com/open-mpi/ompi/issues/3003 to find out
70-
* what's happening here.
71-
*/
72-
#if 0
73-
#if OPAL_TIMER_CYCLE_NATIVE
74-
wtime = ((double) opal_timer_base_get_cycles()) / opal_timer_base_get_freq();
75-
#elif OPAL_TIMER_USEC_NATIVE
76-
wtime = ((double) opal_timer_base_get_usec()) / 1000000.0;
77-
#endif
78-
#else
79-
#if defined(__linux__) && OPAL_HAVE_CLOCK_GETTIME
61+
// We intentionally don't use the OPAL timer framework here. See
62+
// https://github.com/open-mpi/ompi/issues/3003 for more details.
8063
struct timespec tp;
81-
(void) clock_gettime(CLOCK_MONOTONIC, &tp);
82-
if( OPAL_UNLIKELY(0 == ompi_wtime_time_origin.tv_sec) ) {
64+
(void) opal_clock_gettime(&tp);
65+
if (OPAL_UNLIKELY(0 == ompi_wtime_time_origin.tv_sec)) {
8366
ompi_wtime_time_origin = tp;
8467
}
8568
wtime = (double)(tp.tv_nsec - ompi_wtime_time_origin.tv_nsec)/1.0e+9;
8669
wtime += (tp.tv_sec - ompi_wtime_time_origin.tv_sec);
87-
#else
88-
/* Fall back to gettimeofday() if we have nothing else */
89-
struct timeval tv;
90-
gettimeofday(&tv, NULL);
91-
if( OPAL_UNLIKELY(0 == ompi_wtime_time_origin.tv_sec) ) {
92-
ompi_wtime_time_origin = tv;
93-
}
94-
wtime = (double)(tv.tv_usec - ompi_wtime_time_origin.tv_usec) / 1.0e+6;
95-
wtime += (tv.tv_sec - ompi_wtime_time_origin.tv_sec);
96-
#endif
97-
#endif
9870

9971
return wtime;
10072
}

opal/util/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# University of Stuttgart. All rights reserved.
1010
# Copyright (c) 2004-2005 The Regents of the University of California.
1111
# All rights reserved.
12-
# Copyright (c) 2007-2015 Cisco Systems, Inc. All rights reserved.
12+
# Copyright (c) 2007-2022 Cisco Systems, Inc. All rights reserved
1313
# Copyright (c) 2013 NVIDIA Corporation. All rights reserved.
1414
# Copyright (c) 2013 Intel, Inc. All rights reserved
1515
# Copyright (c) 2016 Los Alamos National Security, LLC. All rights
@@ -48,6 +48,7 @@ headers = \
4848
bipartite_graph.h \
4949
bipartite_graph_internal.h \
5050
bit_ops.h \
51+
clock_gettime.h \
5152
cmd_line.h \
5253
crc.h \
5354
daemon_init.h \

opal/util/clock_gettime.h

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (c) 2022 Cisco Systems, Inc. All rights reserved.
3+
* $COPYRIGHT$
4+
*
5+
* Additional copyrights may follow
6+
*
7+
* $HEADER$
8+
*/
9+
10+
/** @file clock_gettime.h
11+
*
12+
* Simple, portable wrappers around clock_gettime(3) and
13+
* clock_getres(3) to always get monotonically-increasing time.
14+
*
15+
* If the underlying OS does not have clock_gettime(3), use
16+
* gettimeofday(3) instead.
17+
*
18+
* We intentionally do not use the OPAL timer framework for
19+
* high-prevision time here; see
20+
* https://github.com/open-mpi/ompi/issues/3003 for more details.
21+
*
22+
* As of Dec 2021, it turns out that CLOCK_MONOTONIC can actually go
23+
* backwards on macOS (!). CLOCK_MONOTONIC does *not* go backwards on
24+
* Linux (or anywhere else we can find), though, even in the presence
25+
* of small NTP time adjustments -- e.g., adjtime(3) simply slightly
26+
* speeds up or slows down the system clock to make it eventually get
27+
* to the desired time. On macOS, we can use CLOCK_MONOTONIC_RAW,
28+
* which never goes backwards.
29+
*
30+
* Hence, for these wrappers, use CLOCK_MONOTONIC_RAW on Darwin, and
31+
* use CLOCK_MONOTONIC everywhere else.
32+
*
33+
* See
34+
* https://github.com/open-mpi/ompi/pull/8057#discussion_r762612710
35+
* and
36+
* https://github.com/open-mpi/ompi/pull/8057#discussion_r762618783
37+
* for more details.
38+
*/
39+
40+
#ifndef OPAL_UTIL_CLOCK_GETTIME_H_
41+
#define OPAL_UTIL_CLOCK_GETTIME_H_
42+
43+
#include "opal_config.h"
44+
45+
#if HAVE_TIME_H
46+
#include <time.h>
47+
#endif
48+
#if HAVE_SYS_TIME_H
49+
#include <sys/time.h>
50+
#endif
51+
52+
#if OPAL_HAVE_CLOCK_GETTIME
53+
#if defined(__darwin__)
54+
#define OPAL_CLOCK_TYPE CLOCK_MONOTONIC_RAW
55+
#else
56+
#define OPAL_CLOCK_TYPE CLOCK_MONOTONIC
57+
#endif
58+
#endif // OPAL_HAVE_CLOCK_GETTIME
59+
60+
#if !defined(HAVE_STRUCT_TIMESPEC_TV_NSEC)
61+
// Make sure that we have struct timespec; if not, define it.
62+
struct timespec {
63+
time_t tv_sec;
64+
long tv_nsec;
65+
};
66+
#endif
67+
68+
/**
69+
* Simple, portable wrapper around clock_gettime(3) for high-precision time.
70+
*
71+
* If the underlying system does not have clock_gettime(3), use
72+
* gettimeofday(3) instead.
73+
*
74+
* @param spec (OUT) Struct to return the time
75+
* @return Return value from underlying clock_gettime()
76+
*/
77+
static inline int opal_clock_gettime(struct timespec *spec)
78+
{
79+
#if OPAL_HAVE_CLOCK_GETTIME
80+
return clock_gettime(OPAL_CLOCK_TYPE, spec);
81+
#else
82+
// If we do not have clock_gettime(), fall back to gettimeofday()
83+
struct timeval tv;
84+
int ret = gettimeofday(&tv, NULL);
85+
86+
spec->tv_sec = tv.tv_sec;
87+
// Elevate the micrseconds to nanoseconds
88+
spec->tv_nsec = tv.tv_usec * 1000;
89+
90+
return ret;
91+
#endif
92+
}
93+
94+
/**
95+
* Simple, portable wrapper around clock_getres(3) for high-precision time.
96+
*
97+
* If the underlying system does not have clock_gettime(3), return usec
98+
* precison (because opal_clock_gettime() will be using gettimeofday(3)).
99+
*
100+
* @param spec (OUT) Struct to return the resolution
101+
* @return Return value from underlying clock_getres()
102+
*/
103+
static inline int opal_clock_getres(struct timespec *spec)
104+
{
105+
#if OPAL_HAVE_CLOCK_GETTIME
106+
return clock_getres(OPAL_CLOCK_TYPE, spec);
107+
#else
108+
// If we don't have clock_gettime(), just return usec precision.
109+
spec->tv_sec = 0;
110+
spec->tv_nsec = 1000;
111+
112+
return 0;
113+
#endif
114+
}
115+
116+
#endif // OPAL_UTIL_CLOCK_GETTIME_H_

0 commit comments

Comments
 (0)