/* * benchmark.h * Simple benchmarking routines for C++11 * * Andy Clifton * August, 2016 */ #ifndef _BENCHMARK_H_ #define _BENCHMARK_H_ #include // for clock_gettime #include // for std::unique_ptr // Types for markers and durations using marker_t = long long; using duration_t = long double; /* start_timing() * Returns a marker value that can later be used to accurately determine the * time taken by a computation. */ inline marker_t start_timing() { std::unique_ptr ts{new timespec}; // It's debatable whether we want CLOCK_PROCESS_CPUTIME_ID or // CLOCK_MONOTONIC. The process clock has the advantage that it does not // include time spent running *other* processes, so if the system is under // load, it will be unaffected. However, it also does not include time // spent executing syscalls, such as for I/O. So doing things like reading // in a huge file will not be counted, even though we would expect that // that time would be measured. if(clock_gettime(CLOCK_MONOTONIC, ts.get()) == 0) { return ts->tv_nsec; } else return 0; } /* get_elapsed_time(start) * Returns the number of seconds elapsed since the starting time (as returned * by start_timing()). * * start: Starting time to measure the duration since. * Returns: elapsed time in seconds since start, or 0 on error. */ inline duration_t get_elapsed_time(marker_t start) { long long now = start_timing(); // Get current time return (1.0 * now - start) / 1000000000L; // convert from nanoseconds to sec } #endif