|
7 | 7 | #ifndef SECP256K1_BENCH_H
|
8 | 8 | #define SECP256K1_BENCH_H
|
9 | 9 |
|
| 10 | +#if defined(_WIN32) |
| 11 | +# include <windows.h> |
| 12 | +#else /* POSIX */ |
| 13 | +# include <time.h> |
| 14 | +#endif |
| 15 | + |
10 | 16 | #include <stdlib.h>
|
11 | 17 | #include <stdint.h>
|
12 | 18 | #include <stdio.h>
|
13 | 19 | #include <string.h>
|
14 | 20 |
|
15 |
| -#if (defined(_MSC_VER) && _MSC_VER >= 1900) |
16 |
| -# include <time.h> |
17 |
| -#else |
18 |
| -# include <sys/time.h> |
19 |
| -#endif |
| 21 | +static int64_t gettime_us(void) { |
| 22 | +#if defined(_WIN32) |
| 23 | + |
| 24 | + LARGE_INTEGER freq, counter; |
| 25 | + QueryPerformanceFrequency(&freq); |
| 26 | + QueryPerformanceCounter(&counter); |
| 27 | + return (int64_t)(counter.QuadPart * 1000000 / freq.QuadPart); |
| 28 | + |
| 29 | +#else /* POSIX */ |
| 30 | + |
| 31 | +# if defined(CLOCK_PROCESS_CPUTIME_ID) |
| 32 | + /* In theory, CLOCK_PROCESS_CPUTIME_ID is only useful if the process is locked to a core, |
| 33 | + * see `man clock_gettime` on Linux. In practice, modern CPUs have synchronized TSCs which |
| 34 | + * address this issue, see https://docs.amd.com/r/en-US/ug1586-onload-user/Timer-TSC-Stability . */ |
| 35 | + const clockid_t clock_type = CLOCK_PROCESS_CPUTIME_ID; |
| 36 | +# elif defined(CLOCK_MONOTONIC) |
| 37 | + /* fallback to wall-clock timer */ |
| 38 | + const clockid_t clock_type = CLOCK_MONOTONIC; |
| 39 | +# else |
| 40 | + /* fallback to less precise wall-clock timer */ |
| 41 | + const clockid_t clock_type = CLOCK_REALTIME; |
| 42 | +# endif |
| 43 | + |
| 44 | + struct timespec ts; |
| 45 | + clock_gettime(clock_type, &ts); |
| 46 | + return (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; |
20 | 47 |
|
21 |
| -static int64_t gettime_i64(void) { |
22 |
| -#if (defined(_MSC_VER) && _MSC_VER >= 1900) |
23 |
| - /* C11 way to get wallclock time */ |
24 |
| - struct timespec tv; |
25 |
| - if (!timespec_get(&tv, TIME_UTC)) { |
26 |
| - fputs("timespec_get failed!", stderr); |
27 |
| - exit(EXIT_FAILURE); |
28 |
| - } |
29 |
| - return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL; |
30 |
| -#else |
31 |
| - struct timeval tv; |
32 |
| - gettimeofday(&tv, NULL); |
33 |
| - return (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * 1000000LL; |
34 | 48 | #endif
|
35 | 49 | }
|
36 | 50 |
|
@@ -105,9 +119,9 @@ static void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setu
|
105 | 119 | if (setup != NULL) {
|
106 | 120 | setup(data);
|
107 | 121 | }
|
108 |
| - begin = gettime_i64(); |
| 122 | + begin = gettime_us(); |
109 | 123 | benchmark(data, iter);
|
110 |
| - total = gettime_i64() - begin; |
| 124 | + total = gettime_us() - begin; |
111 | 125 | if (teardown != NULL) {
|
112 | 126 | teardown(data, iter);
|
113 | 127 | }
|
|
0 commit comments