]>
Commit | Line | Data |
---|---|---|
8cfdb7e0 | 1 | /* Skeleton for benchmark programs. |
6d7e8eda | 2 | Copyright (C) 2013-2023 Free Software Foundation, Inc. |
8cfdb7e0 SP |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, see | |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
8cfdb7e0 SP |
18 | |
19 | #include <string.h> | |
20 | #include <stdint.h> | |
56737508 | 21 | #include <stdbool.h> |
8cfdb7e0 SP |
22 | #include <stdio.h> |
23 | #include <time.h> | |
24 | #include <inttypes.h> | |
43fe811b | 25 | #include "bench-timing.h" |
970c602a | 26 | #include "json-lib.h" |
cb2f668d | 27 | #include "bench-util.h" |
8cfdb7e0 | 28 | |
cb2f668d | 29 | #include "bench-util.c" |
bb7cf681 | 30 | |
d569c6ee | 31 | #define TIMESPEC_AFTER(a, b) \ |
34a5a146 JM |
32 | (((a).tv_sec == (b).tv_sec) \ |
33 | ? ((a).tv_nsec > (b).tv_nsec) \ | |
34 | : ((a).tv_sec > (b).tv_sec)) | |
8cfdb7e0 SP |
35 | int |
36 | main (int argc, char **argv) | |
37 | { | |
d569c6ee | 38 | unsigned long i, k; |
43fe811b SP |
39 | struct timespec runtime; |
40 | timing_t start, end; | |
56737508 | 41 | bool detailed = false; |
970c602a | 42 | json_ctx_t json_ctx; |
56737508 SP |
43 | |
44 | if (argc == 2 && !strcmp (argv[1], "-d")) | |
45 | detailed = true; | |
8cfdb7e0 | 46 | |
cb2f668d | 47 | bench_start (); |
bb7cf681 | 48 | |
d569c6ee | 49 | memset (&runtime, 0, sizeof (runtime)); |
8cfdb7e0 | 50 | |
6103c0a8 | 51 | unsigned long iters = 1000; |
8cfdb7e0 | 52 | |
15eaf6ff SP |
53 | #ifdef BENCH_INIT |
54 | BENCH_INIT (); | |
55 | #endif | |
8cfdb7e0 | 56 | |
970c602a WN |
57 | json_init (&json_ctx, 2, stdout); |
58 | ||
cb5e4aad | 59 | /* Begin function. */ |
970c602a | 60 | json_attr_object_begin (&json_ctx, FUNCNAME); |
cb5e4aad | 61 | |
f0ee064b | 62 | for (int v = 0; v < NUM_VARIANTS; v++) |
8cfdb7e0 | 63 | { |
f0ee064b SP |
64 | /* Run for approximately DURATION seconds. */ |
65 | clock_gettime (CLOCK_MONOTONIC_RAW, &runtime); | |
66 | runtime.tv_sec += DURATION; | |
8cfdb7e0 | 67 | |
beb52f50 | 68 | bool is_bench = strncmp (VARIANT (v), "workload-", 9) == 0; |
f0ee064b | 69 | double d_total_i = 0; |
43fe811b | 70 | timing_t total = 0, max = 0, min = 0x7fffffffffffffff; |
d4505b89 | 71 | timing_t throughput = 0, latency = 0; |
56737508 | 72 | int64_t c = 0; |
beb52f50 | 73 | uint64_t cur; |
d4505b89 | 74 | BENCH_VARS; |
f0ee064b SP |
75 | while (1) |
76 | { | |
beb52f50 | 77 | if (is_bench) |
f0ee064b | 78 | { |
beb52f50 WD |
79 | /* Benchmark a real trace of calls - all samples are iterated |
80 | over once before repeating. This models actual use more | |
81 | accurately than repeating the same sample many times. */ | |
43fe811b | 82 | TIMING_NOW (start); |
f0ee064b | 83 | for (k = 0; k < iters; k++) |
beb52f50 WD |
84 | for (i = 0; i < NUM_SAMPLES (v); i++) |
85 | BENCH_FUNC (v, i); | |
43fe811b | 86 | TIMING_NOW (end); |
43fe811b | 87 | TIMING_DIFF (cur, start, end); |
d4505b89 WD |
88 | TIMING_ACCUM (throughput, cur); |
89 | ||
90 | TIMING_NOW (start); | |
91 | for (k = 0; k < iters; k++) | |
92 | for (i = 0; i < NUM_SAMPLES (v); i++) | |
93 | BENCH_FUNC_LAT (v, i); | |
94 | TIMING_NOW (end); | |
95 | TIMING_DIFF (cur, start, end); | |
96 | TIMING_ACCUM (latency, cur); | |
97 | ||
beb52f50 WD |
98 | d_total_i += iters * NUM_SAMPLES (v); |
99 | } | |
100 | else | |
101 | for (i = 0; i < NUM_SAMPLES (v); i++) | |
102 | { | |
103 | TIMING_NOW (start); | |
104 | for (k = 0; k < iters; k++) | |
105 | BENCH_FUNC (v, i); | |
106 | TIMING_NOW (end); | |
8cfdb7e0 | 107 | |
beb52f50 | 108 | TIMING_DIFF (cur, start, end); |
8cfdb7e0 | 109 | |
beb52f50 WD |
110 | if (cur > max) |
111 | max = cur; | |
d569c6ee | 112 | |
beb52f50 WD |
113 | if (cur < min) |
114 | min = cur; | |
56737508 | 115 | |
beb52f50 WD |
116 | TIMING_ACCUM (total, cur); |
117 | /* Accumulate timings for the value. In the end we will divide | |
118 | by the total iterations. */ | |
119 | RESULT_ACCUM (cur, v, i, c * iters, (c + 1) * iters); | |
120 | ||
121 | d_total_i += iters; | |
122 | } | |
56737508 | 123 | c++; |
f0ee064b | 124 | struct timespec curtime; |
d569c6ee | 125 | |
f0ee064b SP |
126 | memset (&curtime, 0, sizeof (curtime)); |
127 | clock_gettime (CLOCK_MONOTONIC_RAW, &curtime); | |
128 | if (TIMESPEC_AFTER (curtime, runtime)) | |
129 | goto done; | |
130 | } | |
8cfdb7e0 | 131 | |
f0ee064b SP |
132 | double d_total_s; |
133 | double d_iters; | |
d569c6ee | 134 | |
f0ee064b | 135 | done: |
43fe811b | 136 | d_total_s = total; |
f0ee064b | 137 | d_iters = iters; |
d569c6ee | 138 | |
970c602a WN |
139 | /* Begin variant. */ |
140 | json_attr_object_begin (&json_ctx, VARIANT (v)); | |
141 | ||
beb52f50 | 142 | if (is_bench) |
d4505b89 | 143 | { |
44727aec SP |
144 | json_attr_double (&json_ctx, "duration", throughput + latency); |
145 | json_attr_double (&json_ctx, "iterations", 2 * d_total_i); | |
d4505b89 WD |
146 | json_attr_double (&json_ctx, "reciprocal-throughput", |
147 | throughput / d_total_i); | |
148 | json_attr_double (&json_ctx, "latency", latency / d_total_i); | |
149 | json_attr_double (&json_ctx, "max-throughput", | |
150 | d_total_i / throughput * 1000000000.0); | |
151 | json_attr_double (&json_ctx, "min-throughput", | |
152 | d_total_i / latency * 1000000000.0); | |
153 | } | |
beb52f50 WD |
154 | else |
155 | { | |
d4505b89 WD |
156 | json_attr_double (&json_ctx, "duration", d_total_s); |
157 | json_attr_double (&json_ctx, "iterations", d_total_i); | |
beb52f50 WD |
158 | json_attr_double (&json_ctx, "max", max / d_iters); |
159 | json_attr_double (&json_ctx, "min", min / d_iters); | |
160 | json_attr_double (&json_ctx, "mean", d_total_s / d_total_i); | |
161 | } | |
cb5e4aad | 162 | |
beb52f50 | 163 | if (detailed && !is_bench) |
56737508 | 164 | { |
970c602a WN |
165 | json_array_begin (&json_ctx, "timings"); |
166 | ||
56737508 | 167 | for (int i = 0; i < NUM_SAMPLES (v); i++) |
970c602a WN |
168 | json_element_double (&json_ctx, RESULT (v, i)); |
169 | ||
170 | json_array_end (&json_ctx); | |
56737508 | 171 | } |
970c602a WN |
172 | |
173 | /* End variant. */ | |
174 | json_attr_object_end (&json_ctx); | |
f0ee064b | 175 | } |
8cfdb7e0 | 176 | |
cb5e4aad | 177 | /* End function. */ |
970c602a | 178 | json_attr_object_end (&json_ctx); |
cb5e4aad | 179 | |
8cfdb7e0 SP |
180 | return 0; |
181 | } |