diff options
Diffstat (limited to 'tools/perf/builtin-bench.c')
-rw-r--r-- | tools/perf/builtin-bench.c | 245 |
1 files changed, 120 insertions, 125 deletions
diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index e47f90c..77298bf 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -1,18 +1,21 @@ /* + * * builtin-bench.c * - * General benchmarking collections provided by perf + * General benchmarking subsystem provided by perf * * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> + * */ /* - * Available benchmark collection list: * - * sched ... scheduler and IPC performance + * Available subsystem list: + * sched ... scheduler and IPC mechanism * mem ... memory access performance - * numa ... NUMA scheduling and MM performance + * */ + #include "perf.h" #include "util/util.h" #include "util/parse-options.h" @@ -22,92 +25,112 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/prctl.h> -typedef int (*bench_fn_t)(int argc, const char **argv, const char *prefix); - -struct bench { - const char *name; - const char *summary; - bench_fn_t fn; +struct bench_suite { + const char *name; + const char *summary; + int (*fn)(int, const char **, const char *); }; - -#ifdef HAVE_LIBNUMA_SUPPORT -static struct bench numa_benchmarks[] = { - { "mem", "Benchmark for NUMA workloads", bench_numa }, - { "all", "Test all NUMA benchmarks", NULL }, - { NULL, NULL, NULL } + \ +/* sentinel: easy for help */ +#define suite_all { "all", "Test all benchmark suites", NULL } + +#ifdef LIBNUMA_SUPPORT +static struct bench_suite numa_suites[] = { + { "mem", + "Benchmark for NUMA workloads", + bench_numa }, + suite_all, + { NULL, + NULL, + NULL } }; #endif -static struct bench sched_benchmarks[] = { - { "messaging", "Benchmark for scheduling and IPC", bench_sched_messaging }, - { "pipe", "Benchmark for pipe() between two processes", bench_sched_pipe }, - { "all", "Test all scheduler benchmarks", NULL }, - { NULL, NULL, NULL } +static struct bench_suite sched_suites[] = { + { "messaging", + "Benchmark for scheduler and IPC mechanisms", + bench_sched_messaging }, + { "pipe", + "Flood of communication over pipe() between two processes", + bench_sched_pipe }, + suite_all, + { NULL, + NULL, + NULL } }; -static struct bench mem_benchmarks[] = { - { "memcpy", "Benchmark for memcpy()", bench_mem_memcpy }, - { "memset", "Benchmark for memset() tests", bench_mem_memset }, - { "all", "Test all memory benchmarks", NULL }, - { NULL, NULL, NULL } +static struct bench_suite mem_suites[] = { + { "memcpy", + "Simple memory copy in various ways", + bench_mem_memcpy }, + { "memset", + "Simple memory set in various ways", + bench_mem_memset }, + suite_all, + { NULL, + NULL, + NULL } }; -struct collection { - const char *name; - const char *summary; - struct bench *benchmarks; +struct bench_subsys { + const char *name; + const char *summary; + struct bench_suite *suites; }; -static struct collection collections[] = { - { "sched", "Scheduler and IPC benchmarks", sched_benchmarks }, - { "mem", "Memory access benchmarks", mem_benchmarks }, -#ifdef HAVE_LIBNUMA_SUPPORT - { "numa", "NUMA scheduling and MM benchmarks", numa_benchmarks }, +static struct bench_subsys subsystems[] = { +#ifdef LIBNUMA_SUPPORT + { "numa", + "NUMA scheduling and MM behavior", + numa_suites }, #endif - { "all", "All benchmarks", NULL }, - { NULL, NULL, NULL } + { "sched", + "scheduler and IPC mechanism", + sched_suites }, + { "mem", + "memory access performance", + mem_suites }, + { "all", /* sentinel: easy for help */ + "all benchmark subsystem", + NULL }, + { NULL, + NULL, + NULL } }; -/* 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) \ - for (bench = coll->benchmarks; bench->name; bench++) - -static void dump_benchmarks(struct collection *coll) +static void dump_suites(int subsys_index) { - struct bench *bench; + int i; - printf("\n # List of available benchmarks for collection '%s':\n\n", coll->name); + printf("# List of available suites for %s...\n\n", + subsystems[subsys_index].name); - for_each_bench(coll, bench) - printf("%14s: %s\n", bench->name, bench->summary); + for (i = 0; subsystems[subsys_index].suites[i].name; i++) + printf("%14s: %s\n", + subsystems[subsys_index].suites[i].name, + subsystems[subsys_index].suites[i].summary); printf("\n"); + return; } static const char *bench_format_str; - -/* Output/formatting style, exported to benchmark modules: */ int bench_format = BENCH_FORMAT_DEFAULT; static const struct option bench_options[] = { - OPT_STRING('f', "format", &bench_format_str, "default", "Specify format style"), + OPT_STRING('f', "format", &bench_format_str, "default", + "Specify format style"), OPT_END() }; static const char * const bench_usage[] = { - "perf bench [<common options>] <collection> <benchmark> [<options>]", + "perf bench [<common options>] <subsystem> <suite> [<options>]", NULL }; static void print_usage(void) { - struct collection *coll; int i; printf("Usage: \n"); @@ -115,10 +138,11 @@ static void print_usage(void) printf("\t%s\n", bench_usage[i]); printf("\n"); - printf(" # List of all available benchmark collections:\n\n"); + printf("# List of available subsystems...\n\n"); - for_each_collection(coll) - printf("%14s: %s\n", coll->name, coll->summary); + for (i = 0; subsystems[i].name; i++) + printf("%14s: %s\n", + subsystems[i].name, subsystems[i].summary); printf("\n"); } @@ -135,74 +159,44 @@ static int bench_str2int(const char *str) return BENCH_FORMAT_UNKNOWN; } -/* - * 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, - int argc, const char **argv, const char *prefix) -{ - 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; - - ret = fn(argc, argv, prefix); - - free(name); - - return ret; -} - -static void run_collection(struct collection *coll) +static void all_suite(struct bench_subsys *subsys) /* FROM HERE */ { - struct bench *bench; + int i; const char *argv[2]; + struct bench_suite *suites = subsys->suites; argv[1] = NULL; /* * TODO: - * - * Preparing preset parameters for + * preparing preset parameters for * embedded, ordinary PC, HPC, etc... - * would be helpful. + * will be helpful */ - for_each_bench(coll, bench) { - if (!bench->fn) - break; - printf("# Running %s/%s benchmark...\n", coll->name, bench->name); + for (i = 0; suites[i].fn; i++) { + printf("# Running %s/%s benchmark...\n", + subsys->name, + suites[i].name); fflush(stdout); - argv[1] = bench->name; - run_bench(coll->name, bench->name, bench->fn, 1, argv, NULL); + argv[1] = suites[i].name; + suites[i].fn(1, argv, NULL); printf("\n"); } } -static void run_all_collections(void) +static void all_subsystem(void) { - struct collection *coll; - - for_each_collection(coll) - run_collection(coll); + int i; + for (i = 0; subsystems[i].suites; i++) + all_suite(&subsystems[i]); } int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused) { - struct collection *coll; - int ret = 0; + int i, j, status = 0; if (argc < 2) { - /* No collection specified. */ + /* No subsystem specified. */ print_usage(); goto end; } @@ -212,7 +206,7 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused) bench_format = bench_str2int(bench_format_str); if (bench_format == BENCH_FORMAT_UNKNOWN) { - printf("Unknown format descriptor: '%s'\n", bench_format_str); + printf("Unknown format descriptor:%s\n", bench_format_str); goto end; } @@ -222,51 +216,52 @@ int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused) } if (!strcmp(argv[0], "all")) { - run_all_collections(); + all_subsystem(); goto end; } - for_each_collection(coll) { - struct bench *bench; - - if (strcmp(coll->name, argv[0])) + for (i = 0; subsystems[i].name; i++) { + if (strcmp(subsystems[i].name, argv[0])) continue; if (argc < 2) { - /* No bench specified. */ - dump_benchmarks(coll); + /* No suite specified. */ + dump_suites(i); goto end; } if (!strcmp(argv[1], "all")) { - run_collection(coll); + all_suite(&subsystems[i]); goto end; } - for_each_bench(coll, bench) { - if (strcmp(bench->name, argv[1])) + for (j = 0; subsystems[i].suites[j].name; j++) { + if (strcmp(subsystems[i].suites[j].name, argv[1])) continue; if (bench_format == BENCH_FORMAT_DEFAULT) - printf("# Running '%s/%s' benchmark:\n", coll->name, bench->name); + printf("# Running %s/%s benchmark...\n", + subsystems[i].name, + subsystems[i].suites[j].name); fflush(stdout); - ret = run_bench(coll->name, bench->name, bench->fn, argc-1, argv+1, prefix); + status = subsystems[i].suites[j].fn(argc - 1, + argv + 1, prefix); goto end; } if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { - dump_benchmarks(coll); + dump_suites(i); goto end; } - printf("Unknown benchmark: '%s' for collection '%s'\n", argv[1], argv[0]); - ret = 1; + printf("Unknown suite:%s for %s\n", argv[1], argv[0]); + status = 1; goto end; } - printf("Unknown collection: '%s'\n", argv[0]); - ret = 1; + printf("Unknown subsystem:%s\n", argv[0]); + status = 1; end: - return ret; + return status; } |