builtin-bench.c 4.9 KB

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