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 29 struct bench_suite { 30 const char *name; 31 const char *summary; 32 int (*fn)(int, const char **, const char *); 33 }; 34 35 static struct bench_suite sched_suites[] = { 36 { "messaging", 37 "Benchmark for scheduler and IPC mechanisms", 38 bench_sched_messaging }, 39 { "pipe", 40 "Flood of communication over pipe() between two processes", 41 bench_sched_pipe }, 42 { NULL, 43 NULL, 44 NULL } 45 }; 46 47 static struct bench_suite mem_suites[] = { 48 { "memcpy", 49 "Simple memory copy in various ways", 50 bench_mem_memcpy }, 51 { NULL, 52 NULL, 53 NULL } 54 }; 55 56 struct bench_subsys { 57 const char *name; 58 const char *summary; 59 struct bench_suite *suites; 60 }; 61 62 static struct bench_subsys subsystems[] = { 63 { "sched", 64 "scheduler and IPC mechanism", 65 sched_suites }, 66 { "mem", 67 "memory access performance", 68 mem_suites }, 69 { NULL, 70 NULL, 71 NULL } 72 }; 73 74 static void dump_suites(int subsys_index) 75 { 76 int i; 77 78 printf("List of available suites for %s...\n\n", 79 subsystems[subsys_index].name); 80 81 for (i = 0; subsystems[subsys_index].suites[i].name; i++) 82 printf("\t%s: %s\n", 83 subsystems[subsys_index].suites[i].name, 84 subsystems[subsys_index].suites[i].summary); 85 86 printf("\n"); 87 return; 88 } 89 90 static char *bench_format_str; 91 int bench_format = BENCH_FORMAT_DEFAULT; 92 93 static const struct option bench_options[] = { 94 OPT_STRING('f', "format", &bench_format_str, "default", 95 "Specify format style"), 96 OPT_END() 97 }; 98 99 static const char * const bench_usage[] = { 100 "perf bench [<common options>] <subsystem> <suite> [<options>]", 101 NULL 102 }; 103 104 static void print_usage(void) 105 { 106 int i; 107 108 printf("Usage: \n"); 109 for (i = 0; bench_usage[i]; i++) 110 printf("\t%s\n", bench_usage[i]); 111 printf("\n"); 112 113 printf("List of available subsystems...\n\n"); 114 115 for (i = 0; subsystems[i].name; i++) 116 printf("\t%s: %s\n", 117 subsystems[i].name, subsystems[i].summary); 118 printf("\n"); 119 } 120 121 static int bench_str2int(char *str) 122 { 123 if (!str) 124 return BENCH_FORMAT_DEFAULT; 125 126 if (!strcmp(str, BENCH_FORMAT_DEFAULT_STR)) 127 return BENCH_FORMAT_DEFAULT; 128 else if (!strcmp(str, BENCH_FORMAT_SIMPLE_STR)) 129 return BENCH_FORMAT_SIMPLE; 130 131 return BENCH_FORMAT_UNKNOWN; 132 } 133 134 int cmd_bench(int argc, const char **argv, const char *prefix __used) 135 { 136 int i, j, status = 0; 137 138 if (argc < 2) { 139 /* No subsystem specified. */ 140 print_usage(); 141 goto end; 142 } 143 144 argc = parse_options(argc, argv, bench_options, bench_usage, 145 PARSE_OPT_STOP_AT_NON_OPTION); 146 147 bench_format = bench_str2int(bench_format_str); 148 if (bench_format == BENCH_FORMAT_UNKNOWN) { 149 printf("Unknown format descriptor:%s\n", bench_format_str); 150 goto end; 151 } 152 153 if (argc < 1) { 154 print_usage(); 155 goto end; 156 } 157 158 for (i = 0; subsystems[i].name; i++) { 159 if (strcmp(subsystems[i].name, argv[0])) 160 continue; 161 162 if (argc < 2) { 163 /* No suite specified. */ 164 dump_suites(i); 165 goto end; 166 } 167 168 for (j = 0; subsystems[i].suites[j].name; j++) { 169 if (strcmp(subsystems[i].suites[j].name, argv[1])) 170 continue; 171 172 if (bench_format == BENCH_FORMAT_DEFAULT) 173 printf("# Running %s/%s benchmark...\n", 174 subsystems[i].name, 175 subsystems[i].suites[j].name); 176 status = subsystems[i].suites[j].fn(argc - 1, 177 argv + 1, prefix); 178 goto end; 179 } 180 181 if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) { 182 dump_suites(i); 183 goto end; 184 } 185 186 printf("Unknown suite:%s for %s\n", argv[1], argv[0]); 187 status = 1; 188 goto end; 189 } 190 191 printf("Unknown subsystem:%s\n", argv[0]); 192 status = 1; 193 194 end: 195 return status; 196 } 197