diff options
Diffstat (limited to 'tools/perf/bench')
-rw-r--r-- | tools/perf/bench/mem-memcpy-arch.h | 2 | ||||
-rw-r--r-- | tools/perf/bench/mem-memcpy.c | 2 | ||||
-rw-r--r-- | tools/perf/bench/mem-memset-arch.h | 2 | ||||
-rw-r--r-- | tools/perf/bench/mem-memset.c | 2 | ||||
-rw-r--r-- | tools/perf/bench/numa.c | 38 | ||||
-rw-r--r-- | tools/perf/bench/sched-pipe.c | 115 |
6 files changed, 113 insertions, 48 deletions
diff --git a/tools/perf/bench/mem-memcpy-arch.h b/tools/perf/bench/mem-memcpy-arch.h index a72e36cb5394..57b4ed871459 100644 --- a/tools/perf/bench/mem-memcpy-arch.h +++ b/tools/perf/bench/mem-memcpy-arch.h | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | #ifdef ARCH_X86_64 | 2 | #ifdef HAVE_ARCH_X86_64_SUPPORT |
3 | 3 | ||
4 | #define MEMCPY_FN(fn, name, desc) \ | 4 | #define MEMCPY_FN(fn, name, desc) \ |
5 | extern void *fn(void *, const void *, size_t); | 5 | extern void *fn(void *, const void *, size_t); |
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c index 8cdca43016b2..5ce71d3b72cf 100644 --- a/tools/perf/bench/mem-memcpy.c +++ b/tools/perf/bench/mem-memcpy.c | |||
@@ -58,7 +58,7 @@ struct routine routines[] = { | |||
58 | { "default", | 58 | { "default", |
59 | "Default memcpy() provided by glibc", | 59 | "Default memcpy() provided by glibc", |
60 | memcpy }, | 60 | memcpy }, |
61 | #ifdef ARCH_X86_64 | 61 | #ifdef HAVE_ARCH_X86_64_SUPPORT |
62 | 62 | ||
63 | #define MEMCPY_FN(fn, name, desc) { name, desc, fn }, | 63 | #define MEMCPY_FN(fn, name, desc) { name, desc, fn }, |
64 | #include "mem-memcpy-x86-64-asm-def.h" | 64 | #include "mem-memcpy-x86-64-asm-def.h" |
diff --git a/tools/perf/bench/mem-memset-arch.h b/tools/perf/bench/mem-memset-arch.h index a040fa77665b..633800cb0dcb 100644 --- a/tools/perf/bench/mem-memset-arch.h +++ b/tools/perf/bench/mem-memset-arch.h | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | #ifdef ARCH_X86_64 | 2 | #ifdef HAVE_ARCH_X86_64_SUPPORT |
3 | 3 | ||
4 | #define MEMSET_FN(fn, name, desc) \ | 4 | #define MEMSET_FN(fn, name, desc) \ |
5 | extern void *fn(void *, int, size_t); | 5 | extern void *fn(void *, int, size_t); |
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c index 4a2f12081964..9af79d2b18e5 100644 --- a/tools/perf/bench/mem-memset.c +++ b/tools/perf/bench/mem-memset.c | |||
@@ -58,7 +58,7 @@ static const struct routine routines[] = { | |||
58 | { "default", | 58 | { "default", |
59 | "Default memset() provided by glibc", | 59 | "Default memset() provided by glibc", |
60 | memset }, | 60 | memset }, |
61 | #ifdef ARCH_X86_64 | 61 | #ifdef HAVE_ARCH_X86_64_SUPPORT |
62 | 62 | ||
63 | #define MEMSET_FN(fn, name, desc) { name, desc, fn }, | 63 | #define MEMSET_FN(fn, name, desc) { name, desc, fn }, |
64 | #include "mem-memset-x86-64-asm-def.h" | 64 | #include "mem-memset-x86-64-asm-def.h" |
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 30d1c3225b46..d4c83c60b9b2 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c | |||
@@ -429,14 +429,14 @@ static int parse_cpu_list(const char *arg) | |||
429 | return 0; | 429 | return 0; |
430 | } | 430 | } |
431 | 431 | ||
432 | static void parse_setup_cpu_list(void) | 432 | static int parse_setup_cpu_list(void) |
433 | { | 433 | { |
434 | struct thread_data *td; | 434 | struct thread_data *td; |
435 | char *str0, *str; | 435 | char *str0, *str; |
436 | int t; | 436 | int t; |
437 | 437 | ||
438 | if (!g->p.cpu_list_str) | 438 | if (!g->p.cpu_list_str) |
439 | return; | 439 | return 0; |
440 | 440 | ||
441 | dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks); | 441 | dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks); |
442 | 442 | ||
@@ -500,8 +500,12 @@ static void parse_setup_cpu_list(void) | |||
500 | 500 | ||
501 | dprintf("CPUs: %d_%d-%d#%dx%d\n", bind_cpu_0, bind_len, bind_cpu_1, step, mul); | 501 | dprintf("CPUs: %d_%d-%d#%dx%d\n", bind_cpu_0, bind_len, bind_cpu_1, step, mul); |
502 | 502 | ||
503 | BUG_ON(bind_cpu_0 < 0 || bind_cpu_0 >= g->p.nr_cpus); | 503 | if (bind_cpu_0 >= g->p.nr_cpus || bind_cpu_1 >= g->p.nr_cpus) { |
504 | BUG_ON(bind_cpu_1 < 0 || bind_cpu_1 >= g->p.nr_cpus); | 504 | printf("\nTest not applicable, system has only %d CPUs.\n", g->p.nr_cpus); |
505 | return -1; | ||
506 | } | ||
507 | |||
508 | BUG_ON(bind_cpu_0 < 0 || bind_cpu_1 < 0); | ||
505 | BUG_ON(bind_cpu_0 > bind_cpu_1); | 509 | BUG_ON(bind_cpu_0 > bind_cpu_1); |
506 | 510 | ||
507 | for (bind_cpu = bind_cpu_0; bind_cpu <= bind_cpu_1; bind_cpu += step) { | 511 | for (bind_cpu = bind_cpu_0; bind_cpu <= bind_cpu_1; bind_cpu += step) { |
@@ -541,6 +545,7 @@ out: | |||
541 | printf("# NOTE: %d tasks bound, %d tasks unbound\n", t, g->p.nr_tasks - t); | 545 | printf("# NOTE: %d tasks bound, %d tasks unbound\n", t, g->p.nr_tasks - t); |
542 | 546 | ||
543 | free(str0); | 547 | free(str0); |
548 | return 0; | ||
544 | } | 549 | } |
545 | 550 | ||
546 | static int parse_cpus_opt(const struct option *opt __maybe_unused, | 551 | static int parse_cpus_opt(const struct option *opt __maybe_unused, |
@@ -561,14 +566,14 @@ static int parse_node_list(const char *arg) | |||
561 | return 0; | 566 | return 0; |
562 | } | 567 | } |
563 | 568 | ||
564 | static void parse_setup_node_list(void) | 569 | static int parse_setup_node_list(void) |
565 | { | 570 | { |
566 | struct thread_data *td; | 571 | struct thread_data *td; |
567 | char *str0, *str; | 572 | char *str0, *str; |
568 | int t; | 573 | int t; |
569 | 574 | ||
570 | if (!g->p.node_list_str) | 575 | if (!g->p.node_list_str) |
571 | return; | 576 | return 0; |
572 | 577 | ||
573 | dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks); | 578 | dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks); |
574 | 579 | ||
@@ -619,8 +624,12 @@ static void parse_setup_node_list(void) | |||
619 | 624 | ||
620 | dprintf("NODEs: %d-%d #%d\n", bind_node_0, bind_node_1, step); | 625 | dprintf("NODEs: %d-%d #%d\n", bind_node_0, bind_node_1, step); |
621 | 626 | ||
622 | BUG_ON(bind_node_0 < 0 || bind_node_0 >= g->p.nr_nodes); | 627 | if (bind_node_0 >= g->p.nr_nodes || bind_node_1 >= g->p.nr_nodes) { |
623 | BUG_ON(bind_node_1 < 0 || bind_node_1 >= g->p.nr_nodes); | 628 | printf("\nTest not applicable, system has only %d nodes.\n", g->p.nr_nodes); |
629 | return -1; | ||
630 | } | ||
631 | |||
632 | BUG_ON(bind_node_0 < 0 || bind_node_1 < 0); | ||
624 | BUG_ON(bind_node_0 > bind_node_1); | 633 | BUG_ON(bind_node_0 > bind_node_1); |
625 | 634 | ||
626 | for (bind_node = bind_node_0; bind_node <= bind_node_1; bind_node += step) { | 635 | for (bind_node = bind_node_0; bind_node <= bind_node_1; bind_node += step) { |
@@ -651,6 +660,7 @@ out: | |||
651 | printf("# NOTE: %d tasks mem-bound, %d tasks unbound\n", t, g->p.nr_tasks - t); | 660 | printf("# NOTE: %d tasks mem-bound, %d tasks unbound\n", t, g->p.nr_tasks - t); |
652 | 661 | ||
653 | free(str0); | 662 | free(str0); |
663 | return 0; | ||
654 | } | 664 | } |
655 | 665 | ||
656 | static int parse_nodes_opt(const struct option *opt __maybe_unused, | 666 | static int parse_nodes_opt(const struct option *opt __maybe_unused, |
@@ -1110,7 +1120,7 @@ static void *worker_thread(void *__tdata) | |||
1110 | /* Check whether our max runtime timed out: */ | 1120 | /* Check whether our max runtime timed out: */ |
1111 | if (g->p.nr_secs) { | 1121 | if (g->p.nr_secs) { |
1112 | timersub(&stop, &start0, &diff); | 1122 | timersub(&stop, &start0, &diff); |
1113 | if (diff.tv_sec >= g->p.nr_secs) { | 1123 | if ((u32)diff.tv_sec >= g->p.nr_secs) { |
1114 | g->stop_work = true; | 1124 | g->stop_work = true; |
1115 | break; | 1125 | break; |
1116 | } | 1126 | } |
@@ -1157,7 +1167,7 @@ static void *worker_thread(void *__tdata) | |||
1157 | runtime_ns_max += diff.tv_usec * 1000; | 1167 | runtime_ns_max += diff.tv_usec * 1000; |
1158 | 1168 | ||
1159 | if (details >= 0) { | 1169 | if (details >= 0) { |
1160 | printf(" #%2d / %2d: %14.2lf nsecs/op [val: %016lx]\n", | 1170 | printf(" #%2d / %2d: %14.2lf nsecs/op [val: %016"PRIx64"]\n", |
1161 | process_nr, thread_nr, runtime_ns_max / bytes_done, val); | 1171 | process_nr, thread_nr, runtime_ns_max / bytes_done, val); |
1162 | } | 1172 | } |
1163 | fflush(stdout); | 1173 | fflush(stdout); |
@@ -1356,8 +1366,8 @@ static int init(void) | |||
1356 | init_thread_data(); | 1366 | init_thread_data(); |
1357 | 1367 | ||
1358 | tprintf("#\n"); | 1368 | tprintf("#\n"); |
1359 | parse_setup_cpu_list(); | 1369 | if (parse_setup_cpu_list() || parse_setup_node_list()) |
1360 | parse_setup_node_list(); | 1370 | return -1; |
1361 | tprintf("#\n"); | 1371 | tprintf("#\n"); |
1362 | 1372 | ||
1363 | print_summary(); | 1373 | print_summary(); |
@@ -1600,7 +1610,6 @@ static int run_bench_numa(const char *name, const char **argv) | |||
1600 | return 0; | 1610 | return 0; |
1601 | 1611 | ||
1602 | err: | 1612 | err: |
1603 | usage_with_options(numa_usage, options); | ||
1604 | return -1; | 1613 | return -1; |
1605 | } | 1614 | } |
1606 | 1615 | ||
@@ -1701,8 +1710,7 @@ static int bench_all(void) | |||
1701 | BUG_ON(ret < 0); | 1710 | BUG_ON(ret < 0); |
1702 | 1711 | ||
1703 | for (i = 0; i < nr; i++) { | 1712 | for (i = 0; i < nr; i++) { |
1704 | if (run_bench_numa(tests[i][0], tests[i] + 1)) | 1713 | run_bench_numa(tests[i][0], tests[i] + 1); |
1705 | return -1; | ||
1706 | } | 1714 | } |
1707 | 1715 | ||
1708 | printf("\n"); | 1716 | printf("\n"); |
diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 69cfba8d4c6c..07a8d7646a15 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c | |||
@@ -7,9 +7,7 @@ | |||
7 | * Based on pipe-test-1m.c by Ingo Molnar <mingo@redhat.com> | 7 | * Based on pipe-test-1m.c by Ingo Molnar <mingo@redhat.com> |
8 | * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c | 8 | * http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c |
9 | * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> | 9 | * Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> |
10 | * | ||
11 | */ | 10 | */ |
12 | |||
13 | #include "../perf.h" | 11 | #include "../perf.h" |
14 | #include "../util/util.h" | 12 | #include "../util/util.h" |
15 | #include "../util/parse-options.h" | 13 | #include "../util/parse-options.h" |
@@ -28,12 +26,24 @@ | |||
28 | #include <sys/time.h> | 26 | #include <sys/time.h> |
29 | #include <sys/types.h> | 27 | #include <sys/types.h> |
30 | 28 | ||
29 | #include <pthread.h> | ||
30 | |||
31 | struct thread_data { | ||
32 | int nr; | ||
33 | int pipe_read; | ||
34 | int pipe_write; | ||
35 | pthread_t pthread; | ||
36 | }; | ||
37 | |||
31 | #define LOOPS_DEFAULT 1000000 | 38 | #define LOOPS_DEFAULT 1000000 |
32 | static int loops = LOOPS_DEFAULT; | 39 | static int loops = LOOPS_DEFAULT; |
40 | |||
41 | /* Use processes by default: */ | ||
42 | static bool threaded; | ||
33 | 43 | ||
34 | static const struct option options[] = { | 44 | static const struct option options[] = { |
35 | OPT_INTEGER('l', "loop", &loops, | 45 | OPT_INTEGER('l', "loop", &loops, "Specify number of loops"), |
36 | "Specify number of loops"), | 46 | OPT_BOOLEAN('T', "threaded", &threaded, "Specify threads/process based task setup"), |
37 | OPT_END() | 47 | OPT_END() |
38 | }; | 48 | }; |
39 | 49 | ||
@@ -42,13 +52,37 @@ static const char * const bench_sched_pipe_usage[] = { | |||
42 | NULL | 52 | NULL |
43 | }; | 53 | }; |
44 | 54 | ||
45 | int bench_sched_pipe(int argc, const char **argv, | 55 | static void *worker_thread(void *__tdata) |
46 | const char *prefix __maybe_unused) | ||
47 | { | 56 | { |
48 | int pipe_1[2], pipe_2[2]; | 57 | struct thread_data *td = __tdata; |
49 | int m = 0, i; | 58 | int m = 0, i; |
59 | int ret; | ||
60 | |||
61 | for (i = 0; i < loops; i++) { | ||
62 | if (!td->nr) { | ||
63 | ret = read(td->pipe_read, &m, sizeof(int)); | ||
64 | BUG_ON(ret != sizeof(int)); | ||
65 | ret = write(td->pipe_write, &m, sizeof(int)); | ||
66 | BUG_ON(ret != sizeof(int)); | ||
67 | } else { | ||
68 | ret = write(td->pipe_write, &m, sizeof(int)); | ||
69 | BUG_ON(ret != sizeof(int)); | ||
70 | ret = read(td->pipe_read, &m, sizeof(int)); | ||
71 | BUG_ON(ret != sizeof(int)); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | return NULL; | ||
76 | } | ||
77 | |||
78 | int bench_sched_pipe(int argc, const char **argv, const char *prefix __maybe_unused) | ||
79 | { | ||
80 | struct thread_data threads[2], *td; | ||
81 | int pipe_1[2], pipe_2[2]; | ||
50 | struct timeval start, stop, diff; | 82 | struct timeval start, stop, diff; |
51 | unsigned long long result_usec = 0; | 83 | unsigned long long result_usec = 0; |
84 | int nr_threads = 2; | ||
85 | int t; | ||
52 | 86 | ||
53 | /* | 87 | /* |
54 | * why does "ret" exist? | 88 | * why does "ret" exist? |
@@ -58,43 +92,66 @@ int bench_sched_pipe(int argc, const char **argv, | |||
58 | int __maybe_unused ret, wait_stat; | 92 | int __maybe_unused ret, wait_stat; |
59 | pid_t pid, retpid __maybe_unused; | 93 | pid_t pid, retpid __maybe_unused; |
60 | 94 | ||
61 | argc = parse_options(argc, argv, options, | 95 | argc = parse_options(argc, argv, options, bench_sched_pipe_usage, 0); |
62 | bench_sched_pipe_usage, 0); | ||
63 | 96 | ||
64 | BUG_ON(pipe(pipe_1)); | 97 | BUG_ON(pipe(pipe_1)); |
65 | BUG_ON(pipe(pipe_2)); | 98 | BUG_ON(pipe(pipe_2)); |
66 | 99 | ||
67 | pid = fork(); | ||
68 | assert(pid >= 0); | ||
69 | |||
70 | gettimeofday(&start, NULL); | 100 | gettimeofday(&start, NULL); |
71 | 101 | ||
72 | if (!pid) { | 102 | for (t = 0; t < nr_threads; t++) { |
73 | for (i = 0; i < loops; i++) { | 103 | td = threads + t; |
74 | ret = read(pipe_1[0], &m, sizeof(int)); | 104 | |
75 | ret = write(pipe_2[1], &m, sizeof(int)); | 105 | td->nr = t; |
76 | } | 106 | |
77 | } else { | 107 | if (t == 0) { |
78 | for (i = 0; i < loops; i++) { | 108 | td->pipe_read = pipe_1[0]; |
79 | ret = write(pipe_1[1], &m, sizeof(int)); | 109 | td->pipe_write = pipe_2[1]; |
80 | ret = read(pipe_2[0], &m, sizeof(int)); | 110 | } else { |
111 | td->pipe_write = pipe_1[1]; | ||
112 | td->pipe_read = pipe_2[0]; | ||
81 | } | 113 | } |
82 | } | 114 | } |
83 | 115 | ||
84 | gettimeofday(&stop, NULL); | ||
85 | timersub(&stop, &start, &diff); | ||
86 | 116 | ||
87 | if (pid) { | 117 | if (threaded) { |
118 | |||
119 | for (t = 0; t < nr_threads; t++) { | ||
120 | td = threads + t; | ||
121 | |||
122 | ret = pthread_create(&td->pthread, NULL, worker_thread, td); | ||
123 | BUG_ON(ret); | ||
124 | } | ||
125 | |||
126 | for (t = 0; t < nr_threads; t++) { | ||
127 | td = threads + t; | ||
128 | |||
129 | ret = pthread_join(td->pthread, NULL); | ||
130 | BUG_ON(ret); | ||
131 | } | ||
132 | |||
133 | } else { | ||
134 | pid = fork(); | ||
135 | assert(pid >= 0); | ||
136 | |||
137 | if (!pid) { | ||
138 | worker_thread(threads + 0); | ||
139 | exit(0); | ||
140 | } else { | ||
141 | worker_thread(threads + 1); | ||
142 | } | ||
143 | |||
88 | retpid = waitpid(pid, &wait_stat, 0); | 144 | retpid = waitpid(pid, &wait_stat, 0); |
89 | assert((retpid == pid) && WIFEXITED(wait_stat)); | 145 | assert((retpid == pid) && WIFEXITED(wait_stat)); |
90 | } else { | ||
91 | exit(0); | ||
92 | } | 146 | } |
93 | 147 | ||
148 | gettimeofday(&stop, NULL); | ||
149 | timersub(&stop, &start, &diff); | ||
150 | |||
94 | switch (bench_format) { | 151 | switch (bench_format) { |
95 | case BENCH_FORMAT_DEFAULT: | 152 | case BENCH_FORMAT_DEFAULT: |
96 | printf("# Executed %d pipe operations between two tasks\n\n", | 153 | printf("# Executed %d pipe operations between two %s\n\n", |
97 | loops); | 154 | loops, threaded ? "threads" : "processes"); |
98 | 155 | ||
99 | result_usec = diff.tv_sec * 1000000; | 156 | result_usec = diff.tv_sec * 1000000; |
100 | result_usec += diff.tv_usec; | 157 | result_usec += diff.tv_usec; |