Blame view

tools/perf/builtin-bench.c 8.13 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
629cc3566   Hitoshi Mitake   perf bench: Add b...
2
  /*
629cc3566   Hitoshi Mitake   perf bench: Add b...
3
4
   * builtin-bench.c
   *
4157922a9   Ingo Molnar   perf bench: Chang...
5
   * General benchmarking collections provided by perf
629cc3566   Hitoshi Mitake   perf bench: Add b...
6
7
   *
   * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
629cc3566   Hitoshi Mitake   perf bench: Add b...
8
9
10
   */
  
  /*
4157922a9   Ingo Molnar   perf bench: Chang...
11
   * Available benchmark collection list:
629cc3566   Hitoshi Mitake   perf bench: Add b...
12
   *
4157922a9   Ingo Molnar   perf bench: Chang...
13
   *  sched ... scheduler and IPC performance
c2a082030   Davidlohr Bueso   perf bench: Add b...
14
   *  syscall ... System call performance
827f3b497   Hitoshi Mitake   perf bench: Add m...
15
   *  mem   ... memory access performance
4157922a9   Ingo Molnar   perf bench: Chang...
16
   *  numa  ... NUMA scheduling and MM performance
a04397114   Davidlohr Bueso   perf bench: Add f...
17
   *  futex ... Futex performance
121dd9ea0   Davidlohr Bueso   perf bench: Add e...
18
   *  epoll ... Event poll performance
629cc3566   Hitoshi Mitake   perf bench: Add b...
19
   */
4b6ab94ea   Josh Poimboeuf   perf subcmd: Crea...
20
  #include <subcmd/parse-options.h>
629cc3566   Hitoshi Mitake   perf bench: Add b...
21
22
23
24
25
26
  #include "builtin.h"
  #include "bench/bench.h"
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
4157922a9   Ingo Molnar   perf bench: Chang...
27
  #include <sys/prctl.h>
7f7c536f2   Arnaldo Carvalho de Melo   tools lib: Adopt ...
28
  #include <linux/zalloc.h>
629cc3566   Hitoshi Mitake   perf bench: Add b...
29

b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
30
  typedef int (*bench_fn_t)(int argc, const char **argv);
4157922a9   Ingo Molnar   perf bench: Chang...
31
32
33
34
35
  
  struct bench {
  	const char	*name;
  	const char	*summary;
  	bench_fn_t	fn;
629cc3566   Hitoshi Mitake   perf bench: Add b...
36
  };
89fe808ae   Ingo Molnar   tools/perf: Stand...
37
  #ifdef HAVE_LIBNUMA_SUPPORT
4157922a9   Ingo Molnar   perf bench: Chang...
38
39
  static struct bench numa_benchmarks[] = {
  	{ "mem",	"Benchmark for NUMA workloads",			bench_numa		},
aa254af25   Ingo Molnar   perf bench: Run b...
40
  	{ "all",	"Run all NUMA benchmarks",			NULL			},
4157922a9   Ingo Molnar   perf bench: Chang...
41
  	{ NULL,		NULL,						NULL			}
1c13f3c90   Ingo Molnar   perf: Add 'perf b...
42
  };
79d824e31   Peter Hurley   perf tools: Make ...
43
  #endif
1c13f3c90   Ingo Molnar   perf: Add 'perf b...
44

4157922a9   Ingo Molnar   perf bench: Chang...
45
46
47
  static struct bench sched_benchmarks[] = {
  	{ "messaging",	"Benchmark for scheduling and IPC",		bench_sched_messaging	},
  	{ "pipe",	"Benchmark for pipe() between two processes",	bench_sched_pipe	},
aa254af25   Ingo Molnar   perf bench: Run b...
48
  	{ "all",	"Run all scheduler benchmarks",		NULL			},
4157922a9   Ingo Molnar   perf bench: Chang...
49
  	{ NULL,		NULL,						NULL			}
629cc3566   Hitoshi Mitake   perf bench: Add b...
50
  };
c2a082030   Davidlohr Bueso   perf bench: Add b...
51
52
53
54
55
  static struct bench syscall_benchmarks[] = {
  	{ "basic",	"Benchmark for basic getppid(2) calls",		bench_syscall_basic	},
  	{ "all",	"Run all syscall benchmarks",			NULL			},
  	{ NULL,		NULL,						NULL			},
  };
4157922a9   Ingo Molnar   perf bench: Chang...
56
  static struct bench mem_benchmarks[] = {
13b1fdce8   Ingo Molnar   perf bench mem: I...
57
58
  	{ "memcpy",	"Benchmark for memcpy() functions",		bench_mem_memcpy	},
  	{ "memset",	"Benchmark for memset() functions",		bench_mem_memset	},
7c43b0c1d   Ian Rogers   perf bench: Add b...
59
  	{ "find_bit",	"Benchmark for find_bit() functions",		bench_mem_find_bit	},
aa254af25   Ingo Molnar   perf bench: Run b...
60
  	{ "all",	"Run all memory access benchmarks",		NULL			},
4157922a9   Ingo Molnar   perf bench: Chang...
61
  	{ NULL,		NULL,						NULL			}
827f3b497   Hitoshi Mitake   perf bench: Add m...
62
  };
a04397114   Davidlohr Bueso   perf bench: Add f...
63
64
  static struct bench futex_benchmarks[] = {
  	{ "hash",	"Benchmark for futex hash table",               bench_futex_hash	},
27db78307   Davidlohr Bueso   perf bench: Add f...
65
  	{ "wake",	"Benchmark for futex wake calls",               bench_futex_wake	},
d65817b4e   Davidlohr Bueso   perf bench futex:...
66
  	{ "wake-parallel", "Benchmark for parallel futex wake calls",   bench_futex_wake_parallel },
0fb298cf9   Davidlohr Bueso   perf bench: Add f...
67
  	{ "requeue",	"Benchmark for futex requeue calls",            bench_futex_requeue	},
d2f3f5d2e   Davidlohr Bueso   perf bench futex:...
68
69
  	/* pi-futexes */
  	{ "lock-pi",	"Benchmark for futex lock_pi calls",            bench_futex_lock_pi	},
aa254af25   Ingo Molnar   perf bench: Run b...
70
  	{ "all",	"Run all futex benchmarks",			NULL			},
a04397114   Davidlohr Bueso   perf bench: Add f...
71
72
  	{ NULL,		NULL,						NULL			}
  };
ba35fe935   Arnaldo Carvalho de Melo   tools feature: Re...
73
  #ifdef HAVE_EVENTFD_SUPPORT
121dd9ea0   Davidlohr Bueso   perf bench: Add e...
74
75
  static struct bench epoll_benchmarks[] = {
  	{ "wait",	"Benchmark epoll concurrent epoll_waits",       bench_epoll_wait	},
231457ec7   Davidlohr Bueso   perf bench: Add e...
76
  	{ "ctl",	"Benchmark epoll concurrent epoll_ctls",        bench_epoll_ctl		},
121dd9ea0   Davidlohr Bueso   perf bench: Add e...
77
78
79
  	{ "all",	"Run all futex benchmarks",			NULL			},
  	{ NULL,		NULL,						NULL			}
  };
ba35fe935   Arnaldo Carvalho de Melo   tools feature: Re...
80
  #endif // HAVE_EVENTFD_SUPPORT
121dd9ea0   Davidlohr Bueso   perf bench: Add e...
81

2a4b51666   Ian Rogers   perf bench: Add e...
82
83
  static struct bench internals_benchmarks[] = {
  	{ "synthesize", "Benchmark perf event synthesis",	bench_synthesize	},
51876bd45   Ian Rogers   perf bench: Add k...
84
  	{ "kallsyms-parse", "Benchmark kallsyms parsing",	bench_kallsyms_parse	},
0bf02a0d8   Namhyung Kim   perf bench: Add b...
85
  	{ "inject-build-id", "Benchmark build-id injection",	bench_inject_build_id	},
2a4b51666   Ian Rogers   perf bench: Add e...
86
87
  	{ NULL,		NULL,					NULL			}
  };
4157922a9   Ingo Molnar   perf bench: Chang...
88
89
90
91
  struct collection {
  	const char	*name;
  	const char	*summary;
  	struct bench	*benchmarks;
629cc3566   Hitoshi Mitake   perf bench: Add b...
92
  };
4157922a9   Ingo Molnar   perf bench: Chang...
93
  static struct collection collections[] = {
a04397114   Davidlohr Bueso   perf bench: Add f...
94
  	{ "sched",	"Scheduler and IPC benchmarks",			sched_benchmarks	},
c2a082030   Davidlohr Bueso   perf bench: Add b...
95
  	{ "syscall",	"System call benchmarks",			syscall_benchmarks	},
4157922a9   Ingo Molnar   perf bench: Chang...
96
  	{ "mem",	"Memory access benchmarks",			mem_benchmarks		},
89fe808ae   Ingo Molnar   tools/perf: Stand...
97
  #ifdef HAVE_LIBNUMA_SUPPORT
4157922a9   Ingo Molnar   perf bench: Chang...
98
  	{ "numa",	"NUMA scheduling and MM benchmarks",		numa_benchmarks		},
79d824e31   Peter Hurley   perf tools: Make ...
99
  #endif
a04397114   Davidlohr Bueso   perf bench: Add f...
100
  	{"futex",       "Futex stressing benchmarks",                   futex_benchmarks        },
ba35fe935   Arnaldo Carvalho de Melo   tools feature: Re...
101
  #ifdef HAVE_EVENTFD_SUPPORT
121dd9ea0   Davidlohr Bueso   perf bench: Add e...
102
103
  	{"epoll",       "Epoll stressing benchmarks",                   epoll_benchmarks        },
  #endif
2a4b51666   Ian Rogers   perf bench: Add e...
104
  	{ "internals",	"Perf-internals benchmarks",			internals_benchmarks	},
4157922a9   Ingo Molnar   perf bench: Chang...
105
106
  	{ "all",	"All benchmarks",				NULL			},
  	{ NULL,		NULL,						NULL			}
629cc3566   Hitoshi Mitake   perf bench: Add b...
107
  };
4157922a9   Ingo Molnar   perf bench: Chang...
108
109
110
111
112
113
  /* Iterate over all benchmark collections: */
  #define for_each_collection(coll) \
  	for (coll = collections; coll->name; coll++)
  
  /* Iterate over all benchmarks within a collection: */
  #define for_each_bench(coll, bench) \
6eeefccdc   Patrick Palka   perf bench: Fix N...
114
  	for (bench = coll->benchmarks; bench && bench->name; bench++)
4157922a9   Ingo Molnar   perf bench: Chang...
115
116
  
  static void dump_benchmarks(struct collection *coll)
629cc3566   Hitoshi Mitake   perf bench: Add b...
117
  {
4157922a9   Ingo Molnar   perf bench: Chang...
118
  	struct bench *bench;
629cc3566   Hitoshi Mitake   perf bench: Add b...
119

4157922a9   Ingo Molnar   perf bench: Chang...
120
121
122
123
  	printf("
          # List of available benchmarks for collection '%s':
  
  ", coll->name);
629cc3566   Hitoshi Mitake   perf bench: Add b...
124

4157922a9   Ingo Molnar   perf bench: Chang...
125
126
127
  	for_each_bench(coll, bench)
  		printf("%14s: %s
  ", bench->name, bench->summary);
629cc3566   Hitoshi Mitake   perf bench: Add b...
128
129
130
  
  	printf("
  ");
629cc3566   Hitoshi Mitake   perf bench: Add b...
131
  }
edb7c60e2   Arnaldo Carvalho de Melo   perf options: Typ...
132
  static const char *bench_format_str;
4157922a9   Ingo Molnar   perf bench: Chang...
133
134
  
  /* Output/formatting style, exported to benchmark modules: */
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
135
  int bench_format = BENCH_FORMAT_DEFAULT;
b6f0629a9   Davidlohr Bueso   perf bench: Add -...
136
  unsigned int bench_repeat = 10; /* default number of times to repeat the run */
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
137
138
  
  static const struct option bench_options[] = {
7a46a8fd1   Ingo Molnar   perf bench: List ...
139
  	OPT_STRING('f', "format", &bench_format_str, "default|simple", "Specify the output formatting style"),
b6f0629a9   Davidlohr Bueso   perf bench: Add -...
140
  	OPT_UINTEGER('r', "repeat",  &bench_repeat,   "Specify amount of times to repeat the run"),
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
141
142
143
144
  	OPT_END()
  };
  
  static const char * const bench_usage[] = {
4157922a9   Ingo Molnar   perf bench: Chang...
145
  	"perf bench [<common options>] <collection> <benchmark> [<options>]",
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
146
147
148
149
150
  	NULL
  };
  
  static void print_usage(void)
  {
4157922a9   Ingo Molnar   perf bench: Chang...
151
  	struct collection *coll;
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
152
153
154
155
156
157
158
159
160
  	int i;
  
  	printf("Usage: 
  ");
  	for (i = 0; bench_usage[i]; i++)
  		printf("\t%s
  ", bench_usage[i]);
  	printf("
  ");
4157922a9   Ingo Molnar   perf bench: Chang...
161
162
163
  	printf("        # List of all available benchmark collections:
  
  ");
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
164

4157922a9   Ingo Molnar   perf bench: Chang...
165
166
167
  	for_each_collection(coll)
  		printf("%14s: %s
  ", coll->name, coll->summary);
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
168
169
170
  	printf("
  ");
  }
edb7c60e2   Arnaldo Carvalho de Melo   perf options: Typ...
171
  static int bench_str2int(const char *str)
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
172
173
174
175
176
177
178
179
180
181
182
  {
  	if (!str)
  		return BENCH_FORMAT_DEFAULT;
  
  	if (!strcmp(str, BENCH_FORMAT_DEFAULT_STR))
  		return BENCH_FORMAT_DEFAULT;
  	else if (!strcmp(str, BENCH_FORMAT_SIMPLE_STR))
  		return BENCH_FORMAT_SIMPLE;
  
  	return BENCH_FORMAT_UNKNOWN;
  }
4157922a9   Ingo Molnar   perf bench: Chang...
183
184
185
186
187
  /*
   * Run a specific benchmark but first rename the running task's ->comm[]
   * to something meaningful:
   */
  static int run_bench(const char *coll_name, const char *bench_name, bench_fn_t fn,
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
188
  		     int argc, const char **argv)
2044279d1   Hitoshi Mitake   perf bench: Add "...
189
  {
4157922a9   Ingo Molnar   perf bench: Chang...
190
191
192
193
194
195
196
197
198
199
200
201
202
  	int size;
  	char *name;
  	int ret;
  
  	size = strlen(coll_name) + 1 + strlen(bench_name) + 1;
  
  	name = zalloc(size);
  	BUG_ON(!name);
  
  	scnprintf(name, size, "%s-%s", coll_name, bench_name);
  
  	prctl(PR_SET_NAME, name);
  	argv[0] = name;
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
203
  	ret = fn(argc, argv);
4157922a9   Ingo Molnar   perf bench: Chang...
204
205
206
207
208
209
210
211
212
  
  	free(name);
  
  	return ret;
  }
  
  static void run_collection(struct collection *coll)
  {
  	struct bench *bench;
2044279d1   Hitoshi Mitake   perf bench: Add "...
213
  	const char *argv[2];
2044279d1   Hitoshi Mitake   perf bench: Add "...
214
215
216
217
  
  	argv[1] = NULL;
  	/*
  	 * TODO:
4157922a9   Ingo Molnar   perf bench: Chang...
218
219
  	 *
  	 * Preparing preset parameters for
2044279d1   Hitoshi Mitake   perf bench: Add "...
220
  	 * embedded, ordinary PC, HPC, etc...
4157922a9   Ingo Molnar   perf bench: Chang...
221
  	 * would be helpful.
2044279d1   Hitoshi Mitake   perf bench: Add "...
222
  	 */
4157922a9   Ingo Molnar   perf bench: Chang...
223
224
225
226
227
  	for_each_bench(coll, bench) {
  		if (!bench->fn)
  			break;
  		printf("# Running %s/%s benchmark...
  ", coll->name, bench->name);
9b494ea2f   Namhyung Kim   perf bench: Flush...
228
  		fflush(stdout);
2044279d1   Hitoshi Mitake   perf bench: Add "...
229

4157922a9   Ingo Molnar   perf bench: Chang...
230
  		argv[1] = bench->name;
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
231
  		run_bench(coll->name, bench->name, bench->fn, 1, argv);
2044279d1   Hitoshi Mitake   perf bench: Add "...
232
233
234
235
  		printf("
  ");
  	}
  }
4157922a9   Ingo Molnar   perf bench: Chang...
236
  static void run_all_collections(void)
2044279d1   Hitoshi Mitake   perf bench: Add "...
237
  {
4157922a9   Ingo Molnar   perf bench: Chang...
238
239
240
241
  	struct collection *coll;
  
  	for_each_collection(coll)
  		run_collection(coll);
2044279d1   Hitoshi Mitake   perf bench: Add "...
242
  }
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
243
  int cmd_bench(int argc, const char **argv)
629cc3566   Hitoshi Mitake   perf bench: Add b...
244
  {
4157922a9   Ingo Molnar   perf bench: Chang...
245
246
  	struct collection *coll;
  	int ret = 0;
629cc3566   Hitoshi Mitake   perf bench: Add b...
247
248
  
  	if (argc < 2) {
4157922a9   Ingo Molnar   perf bench: Chang...
249
  		/* No collection specified. */
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
250
251
252
  		print_usage();
  		goto end;
  	}
629cc3566   Hitoshi Mitake   perf bench: Add b...
253

386d7e9e5   Hitoshi Mitake   perf bench: Modif...
254
255
256
257
258
  	argc = parse_options(argc, argv, bench_options, bench_usage,
  			     PARSE_OPT_STOP_AT_NON_OPTION);
  
  	bench_format = bench_str2int(bench_format_str);
  	if (bench_format == BENCH_FORMAT_UNKNOWN) {
4157922a9   Ingo Molnar   perf bench: Chang...
259
260
  		printf("Unknown format descriptor: '%s'
  ", bench_format_str);
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
261
262
  		goto end;
  	}
629cc3566   Hitoshi Mitake   perf bench: Add b...
263

b6f0629a9   Davidlohr Bueso   perf bench: Add -...
264
265
266
267
268
  	if (bench_repeat == 0) {
  		printf("Invalid repeat option: Must specify a positive value
  ");
  		goto end;
  	}
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
269
270
  	if (argc < 1) {
  		print_usage();
629cc3566   Hitoshi Mitake   perf bench: Add b...
271
272
  		goto end;
  	}
2044279d1   Hitoshi Mitake   perf bench: Add "...
273
  	if (!strcmp(argv[0], "all")) {
4157922a9   Ingo Molnar   perf bench: Chang...
274
  		run_all_collections();
2044279d1   Hitoshi Mitake   perf bench: Add "...
275
276
  		goto end;
  	}
4157922a9   Ingo Molnar   perf bench: Chang...
277
278
279
280
  	for_each_collection(coll) {
  		struct bench *bench;
  
  		if (strcmp(coll->name, argv[0]))
629cc3566   Hitoshi Mitake   perf bench: Add b...
281
  			continue;
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
282
  		if (argc < 2) {
4157922a9   Ingo Molnar   perf bench: Chang...
283
284
  			/* No bench specified. */
  			dump_benchmarks(coll);
629cc3566   Hitoshi Mitake   perf bench: Add b...
285
286
  			goto end;
  		}
2044279d1   Hitoshi Mitake   perf bench: Add "...
287
  		if (!strcmp(argv[1], "all")) {
4157922a9   Ingo Molnar   perf bench: Chang...
288
  			run_collection(coll);
2044279d1   Hitoshi Mitake   perf bench: Add "...
289
290
  			goto end;
  		}
4157922a9   Ingo Molnar   perf bench: Chang...
291
292
  		for_each_bench(coll, bench) {
  			if (strcmp(bench->name, argv[1]))
629cc3566   Hitoshi Mitake   perf bench: Add b...
293
  				continue;
79e295d4b   Hitoshi Mitake   perf bench: Impro...
294
  			if (bench_format == BENCH_FORMAT_DEFAULT)
4157922a9   Ingo Molnar   perf bench: Chang...
295
296
  				printf("# Running '%s/%s' benchmark:
  ", coll->name, bench->name);
9b494ea2f   Namhyung Kim   perf bench: Flush...
297
  			fflush(stdout);
b0ad8ea66   Arnaldo Carvalho de Melo   perf tools: Remov...
298
  			ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1);
629cc3566   Hitoshi Mitake   perf bench: Add b...
299
300
  			goto end;
  		}
386d7e9e5   Hitoshi Mitake   perf bench: Modif...
301
  		if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
4157922a9   Ingo Molnar   perf bench: Chang...
302
  			dump_benchmarks(coll);
629cc3566   Hitoshi Mitake   perf bench: Add b...
303
304
  			goto end;
  		}
4157922a9   Ingo Molnar   perf bench: Chang...
305
306
307
  		printf("Unknown benchmark: '%s' for collection '%s'
  ", argv[1], argv[0]);
  		ret = 1;
629cc3566   Hitoshi Mitake   perf bench: Add b...
308
309
  		goto end;
  	}
4157922a9   Ingo Molnar   perf bench: Chang...
310
311
312
  	printf("Unknown collection: '%s'
  ", argv[0]);
  	ret = 1;
629cc3566   Hitoshi Mitake   perf bench: Add b...
313
314
  
  end:
4157922a9   Ingo Molnar   perf bench: Chang...
315
  	return ret;
629cc3566   Hitoshi Mitake   perf bench: Add b...
316
  }