Skip to content

Commit 6aff035

Browse files
committed
Refactor benchmark [skip ci]
1 parent b9313c6 commit 6aff035

File tree

4 files changed

+111
-149
lines changed

4 files changed

+111
-149
lines changed

src/bench.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,10 @@ int main(int argc, char** argv) {
253253
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
254254

255255
print_output_table_header_row();
256-
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "ecdsa_verify")) run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters);
256+
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "ecdsa_verify")) run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, iters);
257257

258-
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "ecdsa_sign")) run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters);
259-
if (d || have_flag(argc, argv, "ec") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ec_keygen")) run_benchmark("ec_keygen", bench_keygen_run, bench_keygen_setup, NULL, &data, 10, iters);
258+
if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "ecdsa_sign")) run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, iters);
259+
if (d || have_flag(argc, argv, "ec") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ec_keygen")) run_benchmark("ec_keygen", bench_keygen_run, bench_keygen_setup, NULL, &data, iters);
260260

261261
secp256k1_context_destroy(data.ctx);
262262

src/bench.h

Lines changed: 69 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -7,126 +7,91 @@
77
#ifndef SECP256K1_BENCH_H
88
#define SECP256K1_BENCH_H
99

10+
#if defined(__linux__)
11+
# ifndef _GNU_SOURCE
12+
# define _GNU_SOURCE
13+
# endif
14+
#endif
15+
1016
#include <stdlib.h>
1117
#include <stdint.h>
1218
#include <stdio.h>
1319
#include <string.h>
1420

15-
#if (defined(_MSC_VER) && _MSC_VER >= 1900)
16-
# include <time.h>
17-
#else
18-
# include <sys/time.h>
21+
#if defined(_WIN32)
22+
# include <windows.h>
23+
#elif defined(__APPLE__)
24+
# include <mach/mach.h>
25+
# include <mach/thread_info.h>
26+
# include <mach/kern_return.h>
27+
# include <mach/mach_time.h>
28+
#elif defined(__linux__)
29+
# include <time.h>
1930
#endif
2031

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);
32+
static inline long long gettime_us(void) {
33+
#if defined(_WIN32)
34+
35+
FILETIME create, exit, kernel, user;
36+
if (!GetThreadTimes(GetCurrentThread(), &create, &exit, &kernel, &user)) {
37+
return 0;
38+
}
39+
ULARGE_INTEGER li;
40+
li.LowPart = user.dwLowDateTime;
41+
li.HighPart = user.dwHighDateTime;
42+
return (long long)(li.QuadPart / 10);
43+
44+
#elif defined(__APPLE__)
45+
46+
thread_basic_info_data_t info;
47+
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
48+
if (thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)&info, &count) != KERN_SUCCESS) {
49+
return 0;
50+
}
51+
return (long long)info.user_time.seconds * 1000000LL +
52+
(long long)info.user_time.microseconds;
53+
54+
#elif defined(__linux__)
55+
56+
# if defined(CLOCK_PROCESS_CPUTIME_ID)
57+
clockid_t clock_id = CLOCK_PROCESS_CPUTIME_ID;
58+
# elif defined(CLOCK_MONOTONIC)
59+
clockid_t clock_id = CLOCK_MONOTONIC;
60+
# warning "Benchmark is not immune from system interference."
61+
# else
62+
clockid_t clock_id = CLOCK_REALTIME;
63+
# warning "Benchmark is not immune from system interference."
64+
# endif
65+
66+
struct timespec ts;
67+
if (clock_gettime(clock_id, &ts) != 0) {
68+
return 0;
2869
}
29-
return (int64_t)tv.tv_nsec / 1000 + (int64_t)tv.tv_sec * 1000000LL;
70+
return (long long)ts.tv_sec * 1000000LL + ts.tv_nsec / 1000LL;
71+
3072
#else
31-
struct timeval tv;
32-
gettimeofday(&tv, NULL);
33-
return (int64_t)tv.tv_usec + (int64_t)tv.tv_sec * 1000000LL;
73+
# error "Unsupported platform"
3474
#endif
3575
}
3676

37-
#define FP_EXP (6)
38-
#define FP_MULT (1000000LL)
77+
static void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int iter) {
3978

40-
/* Format fixed point number. */
41-
static void print_number(const int64_t x) {
42-
int64_t x_abs, y;
43-
int c, i, rounding, g; /* g = integer part size, c = fractional part size */
44-
size_t ptr;
45-
char buffer[30];
79+
long long begin, total, avg;
4680

47-
if (x == INT64_MIN) {
48-
/* Prevent UB. */
49-
printf("ERR");
50-
return;
51-
}
52-
x_abs = x < 0 ? -x : x;
53-
54-
/* Determine how many decimals we want to show (more than FP_EXP makes no
55-
* sense). */
56-
y = x_abs;
57-
c = 0;
58-
while (y > 0LL && y < 100LL * FP_MULT && c < FP_EXP) {
59-
y *= 10LL;
60-
c++;
81+
if (setup != NULL) {
82+
setup(data);
6183
}
6284

63-
/* Round to 'c' decimals. */
64-
y = x_abs;
65-
rounding = 0;
66-
for (i = c; i < FP_EXP; ++i) {
67-
rounding = (y % 10) >= 5;
68-
y /= 10;
69-
}
70-
y += rounding;
71-
72-
/* Format and print the number. */
73-
ptr = sizeof(buffer) - 1;
74-
buffer[ptr] = 0;
75-
g = 0;
76-
if (c != 0) { /* non zero fractional part */
77-
for (i = 0; i < c; ++i) {
78-
buffer[--ptr] = '0' + (y % 10);
79-
y /= 10;
80-
}
81-
} else if (c == 0) { /* fractional part is 0 */
82-
buffer[--ptr] = '0';
83-
}
84-
buffer[--ptr] = '.';
85-
do {
86-
buffer[--ptr] = '0' + (y % 10);
87-
y /= 10;
88-
g++;
89-
} while (y != 0);
90-
if (x < 0) {
91-
buffer[--ptr] = '-';
92-
g++;
93-
}
94-
printf("%5.*s", g, &buffer[ptr]); /* Prints integer part */
95-
printf("%-*s", FP_EXP, &buffer[ptr + g]); /* Prints fractional part */
96-
}
85+
begin = gettime_us();
86+
benchmark(data, iter);
87+
total = gettime_us() - begin;
9788

98-
static void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int count, int iter) {
99-
int i;
100-
int64_t min = INT64_MAX;
101-
int64_t sum = 0;
102-
int64_t max = 0;
103-
for (i = 0; i < count; i++) {
104-
int64_t begin, total;
105-
if (setup != NULL) {
106-
setup(data);
107-
}
108-
begin = gettime_i64();
109-
benchmark(data, iter);
110-
total = gettime_i64() - begin;
111-
if (teardown != NULL) {
112-
teardown(data, iter);
113-
}
114-
if (total < min) {
115-
min = total;
116-
}
117-
if (total > max) {
118-
max = total;
119-
}
120-
sum += total;
89+
if (teardown != NULL) {
90+
teardown(data, iter);
12191
}
122-
/* ',' is used as a column delimiter */
123-
printf("%-30s, ", name);
124-
print_number(min * FP_MULT / iter);
125-
printf(" , ");
126-
print_number(((sum * FP_MULT) / count) / iter);
127-
printf(" , ");
128-
print_number(max * FP_MULT / iter);
129-
printf("\n");
92+
93+
avg = total / iter;
94+
printf("%-30s, %lld", name, avg);
13095
}
13196

13297
static int have_flag(int argc, char** argv, char *flag) {
@@ -177,12 +142,9 @@ static int get_iters(int default_iters) {
177142
}
178143

179144
static void print_output_table_header_row(void) {
180-
char* bench_str = "Benchmark"; /* left justified */
181-
char* min_str = " Min(us) "; /* center alignment */
145+
char* bench_str = "Benchmark";
182146
char* avg_str = " Avg(us) ";
183-
char* max_str = " Max(us) ";
184-
printf("%-30s,%-15s,%-15s,%-15s\n", bench_str, min_str, avg_str, max_str);
185-
printf("\n");
147+
printf("%-30s,%-15s\n\n", bench_str, avg_str);
186148
}
187149

188150
#endif /* SECP256K1_BENCH_H */

src/bench_ecmult.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,20 +195,20 @@ static void bench_ecmult_1p_g_teardown(void* arg, int iters) {
195195
static void run_ecmult_bench(bench_data* data, int iters) {
196196
char str[32];
197197
sprintf(str, "ecmult_gen");
198-
run_benchmark(str, bench_ecmult_gen, bench_ecmult_setup, bench_ecmult_gen_teardown, data, 10, iters);
198+
run_benchmark(str, bench_ecmult_gen, bench_ecmult_setup, bench_ecmult_gen_teardown, data, iters);
199199
sprintf(str, "ecmult_const");
200-
run_benchmark(str, bench_ecmult_const, bench_ecmult_setup, bench_ecmult_const_teardown, data, 10, iters);
200+
run_benchmark(str, bench_ecmult_const, bench_ecmult_setup, bench_ecmult_const_teardown, data, iters);
201201
sprintf(str, "ecmult_const_xonly");
202-
run_benchmark(str, bench_ecmult_const_xonly, bench_ecmult_setup, bench_ecmult_const_xonly_teardown, data, 10, iters);
202+
run_benchmark(str, bench_ecmult_const_xonly, bench_ecmult_setup, bench_ecmult_const_xonly_teardown, data, iters);
203203
/* ecmult with non generator point */
204204
sprintf(str, "ecmult_1p");
205-
run_benchmark(str, bench_ecmult_1p, bench_ecmult_setup, bench_ecmult_1p_teardown, data, 10, iters);
205+
run_benchmark(str, bench_ecmult_1p, bench_ecmult_setup, bench_ecmult_1p_teardown, data, iters);
206206
/* ecmult with generator point */
207207
sprintf(str, "ecmult_0p_g");
208-
run_benchmark(str, bench_ecmult_0p_g, bench_ecmult_setup, bench_ecmult_0p_g_teardown, data, 10, iters);
208+
run_benchmark(str, bench_ecmult_0p_g, bench_ecmult_setup, bench_ecmult_0p_g_teardown, data, iters);
209209
/* ecmult with generator and non-generator point. The reported time is per point. */
210210
sprintf(str, "ecmult_1p_g");
211-
run_benchmark(str, bench_ecmult_1p_g, bench_ecmult_setup, bench_ecmult_1p_g_teardown, data, 10, 2*iters);
211+
run_benchmark(str, bench_ecmult_1p_g, bench_ecmult_setup, bench_ecmult_1p_g_teardown, data, 2*iters);
212212
}
213213

214214
static int bench_ecmult_multi_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, void* arg) {
@@ -300,7 +300,7 @@ static void run_ecmult_multi_bench(bench_data* data, size_t count, int includes_
300300
} else {
301301
sprintf(str, "ecmult_multi_%ip", (int)count);
302302
}
303-
run_benchmark(str, bench_ecmult_multi, bench_ecmult_multi_setup, bench_ecmult_multi_teardown, data, 10, count * iters);
303+
run_benchmark(str, bench_ecmult_multi, bench_ecmult_multi_setup, bench_ecmult_multi_teardown, data, count * iters);
304304
}
305305

306306
int main(int argc, char **argv) {

src/bench_internal.c

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -400,38 +400,38 @@ int main(int argc, char **argv) {
400400

401401
print_output_table_header_row();
402402

403-
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "half")) run_benchmark("scalar_half", bench_scalar_half, bench_setup, NULL, &data, 10, iters*100);
404-
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, iters*100);
405-
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, iters*100);
406-
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, iters*10);
407-
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, iters);
408-
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, iters);
409-
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, iters);
410-
411-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "half")) run_benchmark("field_half", bench_field_half, bench_setup, NULL, &data, 10, iters*100);
412-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, iters*100);
413-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, iters*100);
414-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, iters*10);
415-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, iters*10);
416-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, iters);
417-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, iters);
418-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "issquare")) run_benchmark("field_is_square_var", bench_field_is_square_var, bench_setup, NULL, &data, 10, iters);
419-
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, iters);
420-
421-
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, iters*10);
422-
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, iters*10);
423-
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, iters*10);
424-
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, iters*10);
425-
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_zinv_var", bench_group_add_zinv_var, bench_setup, NULL, &data, 10, iters*10);
426-
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, 10, iters);
427-
428-
if (d || have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, iters);
429-
430-
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, iters);
431-
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, iters);
432-
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, iters);
433-
434-
if (d || have_flag(argc, argv, "context")) run_benchmark("context_create", bench_context, bench_setup, NULL, &data, 10, iters);
403+
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "half")) run_benchmark("scalar_half", bench_scalar_half, bench_setup, NULL, &data, iters*100);
404+
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, iters*100);
405+
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, iters*100);
406+
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, iters*10);
407+
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, iters);
408+
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, iters);
409+
if (d || have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, iters);
410+
411+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "half")) run_benchmark("field_half", bench_field_half, bench_setup, NULL, &data, iters*100);
412+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, iters*100);
413+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, iters*100);
414+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, iters*10);
415+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, iters*10);
416+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, iters);
417+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, iters);
418+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "issquare")) run_benchmark("field_is_square_var", bench_field_is_square_var, bench_setup, NULL, &data, iters);
419+
if (d || have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, iters);
420+
421+
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, iters*10);
422+
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, iters*10);
423+
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, iters*10);
424+
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, iters*10);
425+
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_zinv_var", bench_group_add_zinv_var, bench_setup, NULL, &data, iters*10);
426+
if (d || have_flag(argc, argv, "group") || have_flag(argc, argv, "to_affine")) run_benchmark("group_to_affine_var", bench_group_to_affine_var, bench_setup, NULL, &data, iters);
427+
428+
if (d || have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, iters);
429+
430+
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, iters);
431+
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, iters);
432+
if (d || have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, iters);
433+
434+
if (d || have_flag(argc, argv, "context")) run_benchmark("context_create", bench_context, bench_setup, NULL, &data, iters);
435435

436436
return EXIT_SUCCESS;
437437
}

0 commit comments

Comments
 (0)