forked from HighPerLab/c-timer-lib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimer.h
184 lines (163 loc) · 5.46 KB
/
timer.h
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
/* ***************************************************************************
* This header file provides a rudimentary timing facility for C/C++ based
* applications
*
* Makes use of the POSIX standard derived timing mechanisms found within the
* C/C++ standard library. Specifically we use the `clock_gettime` function.
*
* This header file was designed for use for the accurate profiling of
* applications in the context of benchmarking. It was created as part of a
* masters project to investigate the performance portability between OpenCL
* and Single-Assignment C (http://www.sac-home.org/) programming models.
*
* Created by Hans-Nikolai Viessmann (C) 2015 - 2016
*
* Following macros are available to manipulate verbose output:
* - TIMERVER -> 0 (off) 1 (print errors: default) 2 (debug)
*
*/
#ifndef __TIMER_HEADER_GUARD__
#define __TIMER_HEADER_GUARD__
#if __cplusplus
extern "C" {
#endif
#ifndef TIMERVER
/* Verbosity level, the following values are considered valid:
* - 0 : verbosity off
* - 1 : error messages
* - 2 : debug
*/
#define TIMERVER 1
#endif
/** Macros for verbosity **/
#if TIMERVER > 0
#define ERROR(message, ...) \
fprintf(stderr, \
" [ERROR] Timer: (%s:%d) " message "\n" \
, __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define ERROR(message, ...)
#endif
#if TIMERVER > 1
#define DEBUG(message, ...) \
fprintf(stderr, \
" [DEBUG] Timer: (%s:%d) " message "\n" \
, __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define DEBUG(message, ...)
#endif
#define CHECK(cond, message, ...) \
if((cond)) { ERROR(message, ##__VA_ARGS__); goto error; }
/** Error related **/
#define OK 0
#define NOT_ALLOCATED -1
#define CLOCK_FAILED -2
/** Time conversions **/
#define NANO_TO_SEC(time) (time / 1000000000.0)
#define NANO_TO_MSEC(time) (time / 1000000.0)
#define NANO_TO_MCSEC(time) (time / 1000.0)
#define MICRO_TO_SEC(time) (time / 1000000.0)
#define MICRO_TO_MSEC(time) (time / 1000.0)
#define MICRO_TO_NSEC(time) (time * 1000.0)
#define MILLI_TO_SEC(time) (time / 1000.0)
#define MILLI_TO_MCSEC(time) (time * 1000.0)
#define MILLI_TO_NSEC(time) (time * 1000000.0)
#define SEC_TO_MSEC(time) (time * 1000.0)
#define SEC_TO_MCSEC(time) (time * 1000000.0)
#define SEC_TO_NSEC(time) (time * 1000000000.0)
/** Global types **/
/* Enum of time units */
typedef enum
{
s, // seconds
ms, // milli-seconds
us, // micro-seconds
ns, // nano-seconds
unit_check, // used for enum check
none // use the intervals unit
} unit_e;
/* Enum of system clocks */
typedef enum
{
rt,
/* - CLOCK_REALTIME
* System-wide clock that measures real (i.e., wall-clock) time. Setting
* this clock requires appropriate privileges. This clock is affected by
* discontinuous jumps in the system time (e.g., if the system
* administrator manually changes the clock), and by the incremental
* adjustments performed by adjtime(3) and NTP.
*/
rtc,
/* - CLOCK_REALTIME_COARSE (Linux only!)
* A faster but less precise version of CLOCK_REALTIME. Use when you
* need very fast, but not fine-grained timestamps.
*/
mono,
/* - CLOCK_MONOTONIC (Linux only!)
* Clock that cannot be set and represents monotonic time since some
* unspecified starting point. This clock is not affected by
* discontinuous jumps in the system time (e.g., if the system
* administrator manually changes the clock), but is affected by the
* incremental adjustments performed by adjtime(3) and NTP.
*/
monoc,
/* - CLOCK_MONOTONIC_COARSE (Linux only!)
* A faster but less precise version of CLOCK_MONOTONIC. Use when you
* need very fast, but not fine-grained timestamps.
*/
monor,
/* - CLOCK_MONOTONIC_RAW (Linux only!)
* Similar to CLOCK_MONOTONIC, but provides access to a raw
* hardware-based time that is not subject to NTP adjustments or the
* incremental adjustments performed by adjtime(3).
*/
monob,
/* - CLOCK_BOOTTIME (Linux only!)
* Identical to CLOCK_MONOTONIC, except it also includes any time that
* the system is suspended. This allows applications to get a
* suspend-aware monotonic clock without having to deal with the
* complications of CLOCK_REALTIME, which may have discontinuities if
* the time is changed using settimeofday(2).
*/
cpup,
/* - CLOCK_PROCESS_CPUTIME_ID
* High-resolution per-process timer from the CPU.
*/
cput
/* - CLOCK_THREAD_CPUTIME_ID
* Thread-specific CPU-time clock.
*/
} clock_e;
/* Datatype
* struct interval ->
* - name -> string
* - start -> struct timespec
* - stop -> struct timespec
*/
typedef struct
{
char * name;
struct timespec start;
struct timespec stop;
struct timespec elapsed;
clockid_t clockid;
unit_e unit;
clock_e clock;
} interval_t;
/** Declarations **/
char * error_num(int status);
clockid_t set_clock();
struct timespec diff_timespec(struct timespec a, struct timespec b);
int set_timespec(struct timespec ** tims, long sec, long nsec);
char * print_unit(unit_e unit);
int create_interval(interval_t ** tmp, char * name, clock_e ck, unit_e ut);
int get_time(clockid_t clock, struct timespec * time);
int start(interval_t * tmp);
int stop(interval_t * tmp);
double elapsed_interval(interval_t * tmp, unit_e ut);
void print_results(int num, ...);
void print_results_csv(char * comment, int num, ...);
#if __cplusplus
}
#endif
#endif