aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/bench
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/bench')
-rw-r--r--tools/perf/bench/mem-memcpy-arch.h2
-rw-r--r--tools/perf/bench/mem-memcpy.c2
-rw-r--r--tools/perf/bench/mem-memset-arch.h2
-rw-r--r--tools/perf/bench/mem-memset.c2
-rw-r--r--tools/perf/bench/numa.c38
-rw-r--r--tools/perf/bench/sched-pipe.c115
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
432static void parse_setup_cpu_list(void) 432static 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
546static int parse_cpus_opt(const struct option *opt __maybe_unused, 551static 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
564static void parse_setup_node_list(void) 569static 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
656static int parse_nodes_opt(const struct option *opt __maybe_unused, 666static 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
1602err: 1612err:
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
31struct 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
32static int loops = LOOPS_DEFAULT; 39static int loops = LOOPS_DEFAULT;
40
41/* Use processes by default: */
42static bool threaded;
33 43
34static const struct option options[] = { 44static 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
45int bench_sched_pipe(int argc, const char **argv, 55static 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
78int 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;