imate
C++/CUDA Reference
highres_time_stamp.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright 2021, Siavash Ameli <sameli@berkeley.edu>
3  * SPDX-License-Identifier: BSD-3-Clause
4  * SPDX-FileType: SOURCE
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the license found in the LICENSE.txt file in the root
8  * directory of this source tree.
9  */
10 
11 
12 // =======
13 // Headers
14 // =======
15 
16 #include "./highres_time_stamp.h"
17 #include <ctime> // std::time, std::clock
18 #include "stdint.h" // uint64_t
19 
20 // The following macros define either USE_QUERY_PERFORMANCE_COUNTER (if
21 // windows), or USE_CLOCK_GETTIME (if Linux or MacOS>=10.12), or none.
22 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
23 
24  // Use Windows API
25  #include <windows.h> // LARGE_INTEGER, QueryPerformanceCounter
26  #define USE_QUERY_PERFORMANCE_COUNTER
27 
28 #elif defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
29 
30  // POSIX time compilant (Linux)
31  #include <time.h> // timespec, clock_gettime
32  #define USE_CLOCK_GETTIME
33 
34 // MacOS version 10.12 and above has clock_gettime, but _POSIX_TIMERS is
35 // not defined. So, we check this function's availability in a different way.
36 #elif defined(__APPLE__) || defined(__MACH__)
37  #include <TargetConditionals.h>
38  #if TARGET_OS_MAC
39  #include <Availability.h>
40  #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
41  #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
42 
43  // macOS Sierra (10.12) or later. Use clock_gettime
44  #include <time.h> // timespec, clock_gettime
45  #define USE_CLOCK_GETTIME
46 
47  // Define CLOCK_REALTIME in case it is not defined
48  #if !defined(CLOCK_REALTIME)
49  #define CLOCK_REALTIME 0
50  #endif
51 
52  #endif
53  #endif
54  #endif
55 #endif
56 
57 
58 // ======================
59 // Get HighRes Time Stamp
60 // ======================
61 
87 
88 uint64_t get_highres_time_stamp(void)
89 {
90  // Zero means no proper function found for this OS and processor to
91  // support high-precision time counting.
92  uint64_t time_stamp = 0;
93 
94  #if defined(USE_CLOCK_GETTIME)
95 
96  // Using POSIX clock_gettime
97  struct timespec clock;
98  if (clock_gettime(CLOCK_REALTIME, &clock) == -1)
99  {
100  // One means there is an error, but the program continues without
101  // raising an error.
102  time_stamp = 1;
103  }
104 
105  time_stamp = clock.tv_sec * 1e9 + clock.tv_nsec;
106 
107  #elif defined(USE_QUERY_PERFORMANCE_COUNTER)
108 
109  // Using Windows API for query performance counter
110  LARGE_INTEGER ticks;
111  if (!QueryPerformanceCounter(&ticks))
112  {
113  time_stamp = 1;
114  }
115  else
116  {
117  time_stamp = static_cast<uint64_t>(ticks.QuadPart);
118  }
119 
120  #else
121 
122  // Use std::time and std::clock.
123  // Note that std::time has low resolution second accuracy. To improve
124  // it, we add std::clock, which has high-resolution (in UNIX only).
125  // In UNIX, std::clock is the process time with high resolution. In
126  // Windows, note well that std::clock is the wall time with "second"
127  // resolution, and should be avoided.
128  time_stamp = static_cast<uint64_t>(std::time(0)) +
129  static_cast<uint64_t>(std::clock());
130 
131  #endif
132 
133  return time_stamp;
134 }
uint64_t get_highres_time_stamp(void)