linux/tools/perf/builtin-bench.c
<<
>>
Prefs
   1/*
   2 *
   3 * builtin-bench.c
   4 *
   5 * General benchmarking subsystem provided by perf
   6 *
   7 * Copyright (C) 2009, Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
   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
  29struct 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 benchmark suites", NULL }
  37
  38static 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
  51static struct bench_suite mem_suites[] = {
  52        { "memcpy",
  53          "Simple memory copy in various ways",
  54          bench_mem_memcpy },
  55        { "memset",
  56          "Simple memory set in various ways",
  57          bench_mem_memset },
  58        suite_all,
  59        { NULL,
  60          NULL,
  61          NULL             }
  62};
  63
  64struct bench_subsys {
  65        const char *name;
  66        const char *summary;
  67        struct bench_suite *suites;
  68};
  69
  70static struct bench_subsys subsystems[] = {
  71        { "sched",
  72          "scheduler and IPC mechanism",
  73          sched_suites },
  74        { "mem",
  75          "memory access performance",
  76          mem_suites },
  77        { "all",                /* sentinel: easy for help */
  78          "all benchmark subsystem",
  79          NULL },
  80        { NULL,
  81          NULL,
  82          NULL       }
  83};
  84
  85static void dump_suites(int subsys_index)
  86{
  87        int i;
  88
  89        printf("# List of available suites for %s...\n\n",
  90               subsystems[subsys_index].name);
  91
  92        for (i = 0; subsystems[subsys_index].suites[i].name; i++)
  93                printf("%14s: %s\n",
  94                       subsystems[subsys_index].suites[i].name,
  95                       subsystems[subsys_index].suites[i].summary);
  96
  97        printf("\n");
  98        return;
  99}
 100
 101static const char *bench_format_str;
 102int bench_format = BENCH_FORMAT_DEFAULT;
 103
 104static const struct option bench_options[] = {
 105        OPT_STRING('f', "format", &bench_format_str, "default",
 106                    "Specify format style"),
 107        OPT_END()
 108};
 109
 110static const char * const bench_usage[] = {
 111        "perf bench [<common options>] <subsystem> <suite> [<options>]",
 112        NULL
 113};
 114
 115static void print_usage(void)
 116{
 117        int i;
 118
 119        printf("Usage: \n");
 120        for (i = 0; bench_usage[i]; i++)
 121                printf("\t%s\n", bench_usage[i]);
 122        printf("\n");
 123
 124        printf("# List of available subsystems...\n\n");
 125
 126        for (i = 0; subsystems[i].name; i++)
 127                printf("%14s: %s\n",
 128                       subsystems[i].name, subsystems[i].summary);
 129        printf("\n");
 130}
 131
 132static int bench_str2int(const char *str)
 133{
 134        if (!str)
 135                return BENCH_FORMAT_DEFAULT;
 136
 137        if (!strcmp(str, BENCH_FORMAT_DEFAULT_STR))
 138                return BENCH_FORMAT_DEFAULT;
 139        else if (!strcmp(str, BENCH_FORMAT_SIMPLE_STR))
 140                return BENCH_FORMAT_SIMPLE;
 141
 142        return BENCH_FORMAT_UNKNOWN;
 143}
 144
 145static void all_suite(struct bench_subsys *subsys)        /* FROM HERE */
 146{
 147        int i;
 148        const char *argv[2];
 149        struct bench_suite *suites = subsys->suites;
 150
 151        argv[1] = NULL;
 152        /*
 153         * TODO:
 154         * preparing preset parameters for
 155         * embedded, ordinary PC, HPC, etc...
 156         * will be helpful
 157         */
 158        for (i = 0; suites[i].fn; i++) {
 159                printf("# Running %s/%s benchmark...\n",
 160                       subsys->name,
 161                       suites[i].name);
 162
 163                argv[1] = suites[i].name;
 164                suites[i].fn(1, argv, NULL);
 165                printf("\n");
 166        }
 167}
 168
 169static void all_subsystem(void)
 170{
 171        int i;
 172        for (i = 0; subsystems[i].suites; i++)
 173                all_suite(&subsystems[i]);
 174}
 175
 176int cmd_bench(int argc, const char **argv, const char *prefix __maybe_unused)
 177{
 178        int i, j, status = 0;
 179
 180        if (argc < 2) {
 181                /* No subsystem specified. */
 182                print_usage();
 183                goto end;
 184        }
 185
 186        argc = parse_options(argc, argv, bench_options, bench_usage,
 187                             PARSE_OPT_STOP_AT_NON_OPTION);
 188
 189        bench_format = bench_str2int(bench_format_str);
 190        if (bench_format == BENCH_FORMAT_UNKNOWN) {
 191                printf("Unknown format descriptor:%s\n", bench_format_str);
 192                goto end;
 193        }
 194
 195        if (argc < 1) {
 196                print_usage();
 197                goto end;
 198        }
 199
 200        if (!strcmp(argv[0], "all")) {
 201                all_subsystem();
 202                goto end;
 203        }
 204
 205        for (i = 0; subsystems[i].name; i++) {
 206                if (strcmp(subsystems[i].name, argv[0]))
 207                        continue;
 208
 209                if (argc < 2) {
 210                        /* No suite specified. */
 211                        dump_suites(i);
 212                        goto end;
 213                }
 214
 215                if (!strcmp(argv[1], "all")) {
 216                        all_suite(&subsystems[i]);
 217                        goto end;
 218                }
 219
 220                for (j = 0; subsystems[i].suites[j].name; j++) {
 221                        if (strcmp(subsystems[i].suites[j].name, argv[1]))
 222                                continue;
 223
 224                        if (bench_format == BENCH_FORMAT_DEFAULT)
 225                                printf("# Running %s/%s benchmark...\n",
 226                                       subsystems[i].name,
 227                                       subsystems[i].suites[j].name);
 228                        status = subsystems[i].suites[j].fn(argc - 1,
 229                                                            argv + 1, prefix);
 230                        goto end;
 231                }
 232
 233                if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
 234                        dump_suites(i);
 235                        goto end;
 236                }
 237
 238                printf("Unknown suite:%s for %s\n", argv[1], argv[0]);
 239                status = 1;
 240                goto end;
 241        }
 242
 243        printf("Unknown subsystem:%s\n", argv[0]);
 244        status = 1;
 245
 246end:
 247        return status;
 248}
 249
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.