Bitcoin Core 30.99.0
P2P Digital Currency
bench.h
Go to the documentation of this file.
1/***********************************************************************
2 * Copyright (c) 2014 Pieter Wuille *
3 * Distributed under the MIT software license, see the accompanying *
4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5 ***********************************************************************/
6
7#ifndef SECP256K1_BENCH_H
8#define SECP256K1_BENCH_H
9
10#include <stdlib.h>
11#include <stdint.h>
12#include <stdio.h>
13#include <string.h>
14
15#include "tests_common.h"
16
17#define FP_EXP (6)
18#define FP_MULT (1000000LL)
19
20/* Format fixed point number. */
21static void print_number(const int64_t x) {
22 int64_t x_abs, y;
23 int c, i, rounding, g; /* g = integer part size, c = fractional part size */
24 size_t ptr;
25 char buffer[30];
26
27 if (x == INT64_MIN) {
28 /* Prevent UB. */
29 printf("ERR");
30 return;
31 }
32 x_abs = x < 0 ? -x : x;
33
34 /* Determine how many decimals we want to show (more than FP_EXP makes no
35 * sense). */
36 y = x_abs;
37 c = 0;
38 while (y > 0LL && y < 100LL * FP_MULT && c < FP_EXP) {
39 y *= 10LL;
40 c++;
41 }
42
43 /* Round to 'c' decimals. */
44 y = x_abs;
45 rounding = 0;
46 for (i = c; i < FP_EXP; ++i) {
47 rounding = (y % 10) >= 5;
48 y /= 10;
49 }
50 y += rounding;
51
52 /* Format and print the number. */
53 ptr = sizeof(buffer) - 1;
54 buffer[ptr] = 0;
55 g = 0;
56 if (c != 0) { /* non zero fractional part */
57 for (i = 0; i < c; ++i) {
58 buffer[--ptr] = '0' + (y % 10);
59 y /= 10;
60 }
61 } else if (c == 0) { /* fractional part is 0 */
62 buffer[--ptr] = '0';
63 }
64 buffer[--ptr] = '.';
65 do {
66 buffer[--ptr] = '0' + (y % 10);
67 y /= 10;
68 g++;
69 } while (y != 0);
70 if (x < 0) {
71 buffer[--ptr] = '-';
72 g++;
73 }
74 printf("%5.*s", g, &buffer[ptr]); /* Prints integer part */
75 printf("%-*s", FP_EXP, &buffer[ptr + g]); /* Prints fractional part */
76}
77
78static void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int count, int iter) {
79 int i;
80 int64_t min = INT64_MAX;
81 int64_t sum = 0;
82 int64_t max = 0;
83 for (i = 0; i < count; i++) {
84 int64_t begin, total;
85 if (setup != NULL) {
86 setup(data);
87 }
88 begin = gettime_i64();
89 benchmark(data, iter);
90 total = gettime_i64() - begin;
91 if (teardown != NULL) {
92 teardown(data, iter);
93 }
94 if (total < min) {
95 min = total;
96 }
97 if (total > max) {
98 max = total;
99 }
100 sum += total;
101 }
102 /* ',' is used as a column delimiter */
103 printf("%-30s, ", name);
104 print_number(min * FP_MULT / iter);
105 printf(" , ");
106 print_number(((sum * FP_MULT) / count) / iter);
107 printf(" , ");
108 print_number(max * FP_MULT / iter);
109 printf("\n");
110}
111
112static int have_flag(int argc, char** argv, char *flag) {
113 char** argm = argv + argc;
114 argv++;
115 while (argv != argm) {
116 if (strcmp(*argv, flag) == 0) {
117 return 1;
118 }
119 argv++;
120 }
121 return 0;
122}
123
124/* takes an array containing the arguments that the user is allowed to enter on the command-line
125 returns:
126 - 1 if the user entered an invalid argument
127 - 0 if all the user entered arguments are valid */
128static int have_invalid_args(int argc, char** argv, char** valid_args, size_t n) {
129 size_t i;
130 int found_valid;
131 char** argm = argv + argc;
132 argv++;
133
134 while (argv != argm) {
135 found_valid = 0;
136 for (i = 0; i < n; i++) {
137 if (strcmp(*argv, valid_args[i]) == 0) {
138 found_valid = 1; /* user entered a valid arg from the list */
139 break;
140 }
141 }
142 if (found_valid == 0) {
143 return 1; /* invalid arg found */
144 }
145 argv++;
146 }
147 return 0;
148}
149
150static int get_iters(int default_iters) {
151 char* env = getenv("SECP256K1_BENCH_ITERS");
152 if (env) {
153 return strtol(env, NULL, 0);
154 } else {
155 return default_iters;
156 }
157}
158
160 char* bench_str = "Benchmark"; /* left justified */
161 char* min_str = " Min(us) "; /* center alignment */
162 char* avg_str = " Avg(us) ";
163 char* max_str = " Max(us) ";
164 printf("%-30s,%-15s,%-15s,%-15s\n", bench_str, min_str, avg_str, max_str);
165 printf("\n");
166}
167
168#endif /* SECP256K1_BENCH_H */
volatile double sum
Definition: examples.cpp:10
void printf(FormatStringCheck< sizeof...(Args)> fmt, const Args &... args)
Format list of arguments to std::cout, according to the given format string.
Definition: tinyformat.h:1096
const char * name
Definition: rest.cpp:50
static int get_iters(int default_iters)
Definition: bench.h:150
#define FP_EXP
Definition: bench.h:17
static void print_output_table_header_row(void)
Definition: bench.h:159
static void print_number(const int64_t x)
Definition: bench.h:21
#define FP_MULT
Definition: bench.h:18
static void run_benchmark(char *name, void(*benchmark)(void *, int), void(*setup)(void *), void(*teardown)(void *, int), void *data, int count, int iter)
Definition: bench.h:78
static int have_invalid_args(int argc, char **argv, char **valid_args, size_t n)
Definition: bench.h:128
static int have_flag(int argc, char **argv, char *flag)
Definition: bench.h:112
static int teardown(void)
Definition: tests.c:7819
static int setup(void)
Definition: tests.c:7796
static int64_t gettime_i64(void)
Definition: tests_common.h:26
static int count