util.h (2543B)
1 #if defined(__linux__) 2 # define _GNU_SOURCE 3 # include <sched.h> 4 #endif 5 6 #include <limits.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <time.h> 11 #include <unistd.h> 12 13 14 15 #ifdef BENCHMARK_LIB 16 # include BENCHMARK_LIB 17 #else 18 # include "../zahl.h" 19 # define BIGINT_LIBRARY "libzahl" 20 #endif 21 22 #ifndef LIBRARY_SUFFIX 23 # define LIBRARY_SUFFIX "" 24 #endif 25 26 #ifndef USE_CPU 27 # define USE_CPU 0 28 #endif 29 30 31 #ifndef CLOCK_MONOTONIC_RAW 32 # define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC 33 #endif 34 35 #ifdef __x86_64__ 36 # define RDTSC_MAYBE_SUPPORTED 37 #endif 38 39 #if !defined(USE_RDTSC) && !defined(USE_CLOCK) && !defined(USE_GETTIME) 40 # if 1 && defined(RDTSC_MAYBE_SUPPORTED) && defined(__linux__) 41 # define USE_RDTSC 42 # elif 1 43 # define USE_CLOCK 44 # else 45 # define USE_GETTIME 46 # endif 47 #endif 48 49 50 51 extern char timebuf[512]; 52 extern unsigned long long int freq; 53 54 #ifndef COMPILING_UTIL_C 55 56 static struct timespec dur; 57 58 # if defined(USE_RDTSC) && defined(__x86_64__) 59 typedef unsigned long long int rdtsc_t; 60 static unsigned int start_high, start_low, end_high, end_low; 61 # define rdtsc_join(low, high) ((rdtsc_t)(low) | (((rdtsc_t)(high)) << 32)) 62 # define TIC (rdtsc(&start_low, &start_high)) 63 # define TOC\ 64 do {\ 65 rdtsc_t dur_cycles;\ 66 double dur_seconds;\ 67 rdtsc(&end_low, &end_high);\ 68 dur_cycles = rdtsc_join(end_low, end_high);\ 69 dur_cycles -= rdtsc_join(start_low, start_high);\ 70 dur_seconds = (double)dur_cycles;\ 71 dur_seconds /= 1000 * (double)freq;\ 72 dur_seconds -= (double)(dur.tv_sec = (int)dur_seconds);\ 73 dur.tv_nsec = (long int)(dur_seconds * 1000000000L);\ 74 } while (0) 75 static inline void 76 rdtsc(unsigned int *low, unsigned int *high) 77 { 78 __asm__ __volatile__ ("rdtsc" : "=a"(*low), "=d"(*high)); 79 } 80 81 # elif defined(USE_CLOCK) 82 static clock_t start, end; 83 # define TIC (start = clock()) 84 # define TOC\ 85 do {\ 86 end = clock();\ 87 dur.tv_sec = (end - start) / 1000000ULL;\ 88 dur.tv_nsec = ((end - start) % 1000000ULL) * 1000;\ 89 } while (0) 90 91 # elif defined(USE_GETTIME) 92 static struct timespec start; 93 # define TIC clock_gettime(CLOCK_MONOTONIC_RAW, &start) 94 # define TOC\ 95 do {\ 96 clock_gettime(CLOCK_MONOTONIC_RAW, &dur);\ 97 dur.tv_sec -= start.tv_sec;\ 98 dur.tv_nsec -= start.tv_nsec;\ 99 if (dur.tv_nsec < 0) {\ 100 dur.tv_nsec += 1000000000L;\ 101 dur.tv_sec -= 1;\ 102 }\ 103 } while (0) 104 105 # endif 106 107 108 # define TICKS ((unsigned long long int)(dur.tv_sec) * 1000000000ULL + (unsigned long long int)(dur.tv_nsec)) 109 # define STIME (sprintf(timebuf, "%lli.%09li", (long long)(dur.tv_sec), dur.tv_nsec), timebuf) 110 111 #endif 112 113 114 void benchmark_init(void);