Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/tools/perf/builtin-bench.c
10820 views
1
/*
2
*
3
* builtin-bench.c
4
*
5
* General benchmarking subsystem provided by perf
6
*
7
* Copyright (C) 2009, Hitoshi Mitake <[email protected]>
8
*
9
*/
10
11
/*
12
*
13
* Available subsystem list:
14
* sched ... scheduler and IPC mechanism
15
* mem ... memory access performance
16
*
17
*/
18
19
#include "perf.h"
20
#include "util/util.h"
21
#include "util/parse-options.h"
22
#include "builtin.h"
23
#include "bench/bench.h"
24
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <string.h>
28
29
struct bench_suite {
30
const char *name;
31
const char *summary;
32
int (*fn)(int, const char **, const char *);
33
};
34
\
35
/* sentinel: easy for help */
36
#define suite_all { "all", "test all suite (pseudo suite)", NULL }
37
38
static struct bench_suite sched_suites[] = {
39
{ "messaging",
40
"Benchmark for scheduler and IPC mechanisms",
41
bench_sched_messaging },
42
{ "pipe",
43
"Flood of communication over pipe() between two processes",
44
bench_sched_pipe },
45
suite_all,
46
{ NULL,
47
NULL,
48
NULL }
49
};
50
51
static struct bench_suite mem_suites[] = {
52
{ "memcpy",
53
"Simple memory copy in various ways",
54
bench_mem_memcpy },
55
suite_all,
56
{ NULL,
57
NULL,
58
NULL }
59
};
60
61
struct bench_subsys {
62
const char *name;
63
const char *summary;
64
struct bench_suite *suites;
65
};
66
67
static struct bench_subsys subsystems[] = {
68
{ "sched",
69
"scheduler and IPC mechanism",
70
sched_suites },
71
{ "mem",
72
"memory access performance",
73
mem_suites },
74
{ "all", /* sentinel: easy for help */
75
"test all subsystem (pseudo subsystem)",
76
NULL },
77
{ NULL,
78
NULL,
79
NULL }
80
};
81
82
static void dump_suites(int subsys_index)
83
{
84
int i;
85
86
printf("# List of available suites for %s...\n\n",
87
subsystems[subsys_index].name);
88
89
for (i = 0; subsystems[subsys_index].suites[i].name; i++)
90
printf("%14s: %s\n",
91
subsystems[subsys_index].suites[i].name,
92
subsystems[subsys_index].suites[i].summary);
93
94
printf("\n");
95
return;
96
}
97
98
static const char *bench_format_str;
99
int bench_format = BENCH_FORMAT_DEFAULT;
100
101
static const struct option bench_options[] = {
102
OPT_STRING('f', "format", &bench_format_str, "default",
103
"Specify format style"),
104
OPT_END()
105
};
106
107
static const char * const bench_usage[] = {
108
"perf bench [<common options>] <subsystem> <suite> [<options>]",
109
NULL
110
};
111
112
static void print_usage(void)
113
{
114
int i;
115
116
printf("Usage: \n");
117
for (i = 0; bench_usage[i]; i++)
118
printf("\t%s\n", bench_usage[i]);
119
printf("\n");
120
121
printf("# List of available subsystems...\n\n");
122
123
for (i = 0; subsystems[i].name; i++)
124
printf("%14s: %s\n",
125
subsystems[i].name, subsystems[i].summary);
126
printf("\n");
127
}
128
129
static int bench_str2int(const char *str)
130
{
131
if (!str)
132
return BENCH_FORMAT_DEFAULT;
133
134
if (!strcmp(str, BENCH_FORMAT_DEFAULT_STR))
135
return BENCH_FORMAT_DEFAULT;
136
else if (!strcmp(str, BENCH_FORMAT_SIMPLE_STR))
137
return BENCH_FORMAT_SIMPLE;
138
139
return BENCH_FORMAT_UNKNOWN;
140
}
141
142
static void all_suite(struct bench_subsys *subsys) /* FROM HERE */
143
{
144
int i;
145
const char *argv[2];
146
struct bench_suite *suites = subsys->suites;
147
148
argv[1] = NULL;
149
/*
150
* TODO:
151
* preparing preset parameters for
152
* embedded, ordinary PC, HPC, etc...
153
* will be helpful
154
*/
155
for (i = 0; suites[i].fn; i++) {
156
printf("# Running %s/%s benchmark...\n",
157
subsys->name,
158
suites[i].name);
159
160
argv[1] = suites[i].name;
161
suites[i].fn(1, argv, NULL);
162
printf("\n");
163
}
164
}
165
166
static void all_subsystem(void)
167
{
168
int i;
169
for (i = 0; subsystems[i].suites; i++)
170
all_suite(&subsystems[i]);
171
}
172
173
int cmd_bench(int argc, const char **argv, const char *prefix __used)
174
{
175
int i, j, status = 0;
176
177
if (argc < 2) {
178
/* No subsystem specified. */
179
print_usage();
180
goto end;
181
}
182
183
argc = parse_options(argc, argv, bench_options, bench_usage,
184
PARSE_OPT_STOP_AT_NON_OPTION);
185
186
bench_format = bench_str2int(bench_format_str);
187
if (bench_format == BENCH_FORMAT_UNKNOWN) {
188
printf("Unknown format descriptor:%s\n", bench_format_str);
189
goto end;
190
}
191
192
if (argc < 1) {
193
print_usage();
194
goto end;
195
}
196
197
if (!strcmp(argv[0], "all")) {
198
all_subsystem();
199
goto end;
200
}
201
202
for (i = 0; subsystems[i].name; i++) {
203
if (strcmp(subsystems[i].name, argv[0]))
204
continue;
205
206
if (argc < 2) {
207
/* No suite specified. */
208
dump_suites(i);
209
goto end;
210
}
211
212
if (!strcmp(argv[1], "all")) {
213
all_suite(&subsystems[i]);
214
goto end;
215
}
216
217
for (j = 0; subsystems[i].suites[j].name; j++) {
218
if (strcmp(subsystems[i].suites[j].name, argv[1]))
219
continue;
220
221
if (bench_format == BENCH_FORMAT_DEFAULT)
222
printf("# Running %s/%s benchmark...\n",
223
subsystems[i].name,
224
subsystems[i].suites[j].name);
225
status = subsystems[i].suites[j].fn(argc - 1,
226
argv + 1, prefix);
227
goto end;
228
}
229
230
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
231
dump_suites(i);
232
goto end;
233
}
234
235
printf("Unknown suite:%s for %s\n", argv[1], argv[0]);
236
status = 1;
237
goto end;
238
}
239
240
printf("Unknown subsystem:%s\n", argv[0]);
241
status = 1;
242
243
end:
244
return status;
245
}
246
247