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
|
#include "cycleclock.h"
#include <cctk.h>
// Find a good wall clock timer
#ifdef _OPENMP
# include <omp.h>
#endif
#ifdef HAVE_CAPABILITY_MPI
# include <mpi.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
static double cycleclock_tick = -1.0; // uninitialised
#ifdef HAVE_SYS_TIME_H
static double get_sys_time()
{
timeval tp;
gettimeofday(&tp, NULL);
return tp.tv_sec + 1.0e-6 * tp.tv_usec;
}
#endif
void measure_tick()
{
// Make a few warm-up measurements
getticks();
getticks();
getticks();
#ifdef _OPENMP
if (cycleclock_tick < 0.0) {
// Use omp_get_sys_time to calibrate the timer
CCTK_INFO("Measuring CycleClock tick via OpenMP...");
ticks const rstart = getticks();
double const wstart = omp_get_wtime();
while (omp_get_wtime() < wstart + 0.1) {
// do nothing, just wait
}
ticks const rend = getticks();
double const wend = omp_get_wtime();
cycleclock_tick = (wend - wstart) / elapsed(rend, rstart);
}
#endif
#ifdef HAVE_CAPABILITY_MPI
if (cycleclock_tick < 0.0) {
// Use MPI_Wtime to calibrate the timer
CCTK_INFO("Measuring CycleClock tick via MPI...");
ticks const rstart = getticks();
double const wstart = MPI_Wtime();
while (MPI_Wtime() < wstart + 0.1) {
// do nothing, just wait
}
ticks const rend = getticks();
double const wend = MPI_Wtime();
cycleclock_tick = (wend - wstart) / elapsed(rend, rstart);
}
#endif
#ifdef HAVE_SYS_TIME_H
if (cycleclock_tick < 0.0) {
// Use gettimeofday to calibrate the timer
CCTK_INFO("Measuring CycleClock tick via gettimeofday...");
ticks const rstart = getticks();
double const wstart = get_sys_time();
while (get_sys_time() < wstart + 0.1) {
// do nothing, just wait
}
ticks const rend = getticks();
double const wend = get_sys_time();
cycleclock_tick = (wend - wstart) / elapsed(rend, rstart);
}
#endif
if (cycleclock_tick < 0.0) {
// Give up; just set the time scale to 1
CCTK_INFO("Could not measure CycleClock tick");
cycleclock_tick = 1.0;
}
CCTK_VInfo(CCTK_THORNSTRING,
"Calibrated CycleClock: %g ns per clock tick (%g GHz)",
1.0e9 * cycleclock_tick, 1.0e-9 / cycleclock_tick);
}
double seconds_per_tick()
{
// if (CCTK_BUILTIN_EXPECT(cycleclock_tick < 0.0, false)) {
// CCTK_WARN(CCTK_WARN_ALERT,
// "Thorn CycleClock has not been activated; the first measurements may be wrong");
// measure_tick();
// }
return cycleclock_tick;
}
|