Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 333 lines (302 sloc) 8.469 kb
2557d8a @avsm add atomicio and utility functions
authored
1 /*
2 Copyright (c) 2011 Anil Madhavapeddy <anil@recoil.org>
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
3 Copyright (c) 2011 Steven Smith <sos22@cam.ac.uk>
2557d8a @avsm add atomicio and utility functions
authored
4
5 Permission is hereby granted, free of charge, to any person
6 obtaining a copy of this software and associated documentation
7 files (the "Software"), to deal in the Software without
8 restriction, including without limitation the rights to use,
9 copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following
12 conditions:
13
14 The above copyright notice and this permission notice shall be
15 included in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 OTHER DEALINGS IN THE SOFTWARE.
25 */
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
26 #include <sys/mman.h>
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
27 #include <sys/time.h>
13ad06d More summary statistics.
Steven Smith authored
28 #include <assert.h>
2557d8a @avsm add atomicio and utility functions
authored
29 #include <unistd.h>
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
30 #include <fcntl.h>
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
31 #include <math.h>
cb7e4c5 Merge branch 'master' of git://github.com/avsm/ipc-bench
Steven Smith authored
32 #include <sched.h>
f14f79d Try to make the log files a bit easier to parse.
Steven Smith authored
33 #include <stdarg.h>
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
34 #include <stdbool.h>
2557d8a @avsm add atomicio and utility functions
authored
35 #include <stdlib.h>
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
36 #include <stdio.h>
37 #include <string.h>
2557d8a @avsm add atomicio and utility functions
authored
38 #include <err.h>
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
39 #include <inttypes.h>
2557d8a @avsm add atomicio and utility functions
authored
40 #include "atomicio.h"
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
41 #include "xutil.h"
d950aa3 Simplify the latency_test and thr_test macros a bit.
Steven Smith authored
42 #include "test.h"
2557d8a @avsm add atomicio and utility functions
authored
43
44 void *
45 xmalloc(size_t size)
46 {
47 void *buf;
48 buf = malloc(size);
49 if (buf == NULL)
50 err(1, "xmalloc");
51 return buf;
52 }
53
54 void
55 xread(int fd, void *buf, size_t count)
56 {
57 ssize_t r;
58 r = atomicio(read, fd, buf, count);
59 if (r != count)
60 err(1, "xread");
61 }
62
63 void
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
64 xwrite(int fd, const void *buf, size_t count)
2557d8a @avsm add atomicio and utility functions
authored
65 {
66 ssize_t r;
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
67 r = atomicio(vwrite, fd, (void *)buf, count);
2557d8a @avsm add atomicio and utility functions
authored
68 if (r != count)
69 err(1, "xwrite");
70 }
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
71
72 static double
73 get_tsc_freq(void)
74 {
75 double estimates[5];
76 int nr_estimates;
77 struct timeval start;
78 struct timeval now;
79 unsigned long start_tsc;
80 unsigned long end_tsc;
81 double low_estimate, high_estimate;
82 double total;
83 int i;
84
85 while (1) {
86 for (nr_estimates = 0; nr_estimates < 5; nr_estimates++) {
87 gettimeofday(&start, NULL);
88 start_tsc = rdtsc();
89 do {
90 gettimeofday(&now, NULL);
91 now.tv_sec -= start.tv_sec;
92 now.tv_usec -= start.tv_usec;
93 if (now.tv_usec < 0) {
94 now.tv_sec--;
95 now.tv_usec += 1e6;
96 }
97 } while (now.tv_usec < 1e4);
98 end_tsc = rdtsc();
99 estimates[nr_estimates] = (end_tsc - start_tsc) / (now.tv_usec * 1e-6);
100 }
101
102 /* Check for anomalies */
103 low_estimate = estimates[0];
104 high_estimate = estimates[0];
105 for (i = 1; i < nr_estimates; i++) {
106 if (estimates[i] < low_estimate)
107 low_estimate = estimates[i];
108 if (estimates[i] > high_estimate)
109 high_estimate = estimates[i];
110 }
111 /* Accept if range of estimates is less than 1% */
112 if (high_estimate < low_estimate * 1.01)
113 break;
114 /* Otherwise try again */
115 }
116
117 /* Use an arithmetic mean. Should arguably be using harmonic mean
118 here, but since the thinks we're averaging vary by less than 1%
119 it shouldn't make much difference. */
120 total = 0;
121 for (i = 0; i < nr_estimates; i++)
122 total += estimates[i];
123 return total / nr_estimates;
124 }
125
f14f79d Try to make the log files a bit easier to parse.
Steven Smith authored
126 static FILE *
127 open_logfile(test_data *td, const char *file)
128 {
129 char *path;
130 FILE *res;
131
132 assert(td->output_dir != NULL);
133
134 if (asprintf(&path,
135 "%s/%02d-%s-%s.log",
136 td->output_dir,
137 td->num,
138 td->name,
139 file) < 0)
140 err(1, "asprintf()");
141 res = fopen(path, "a");
142 if (!res)
143 err(1, "fopen(%s)", path);
144 free(path);
145 return res;
146 }
147
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
148 void
22c5980 Rework thigns a bit so that the tests themselves dump raw timestamps
Steven Smith authored
149 dump_tsc_counters(test_data *td, unsigned long *counts, int nr_samples)
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
150 {
1683c80 Move summarise_tsc_counters.c back into the main test pipeline, so
Steven Smith authored
151 FILE *f = open_logfile(td, "tsc");
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
152 double clock_freq = get_tsc_freq();
153 int i;
1683c80 Move summarise_tsc_counters.c back into the main test pipeline, so
Steven Smith authored
154 double *times = (double *)counts;
155 times = calloc(sizeof(double), nr_samples);
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
156 for (i = 0; i < nr_samples; i++)
1683c80 Move summarise_tsc_counters.c back into the main test pipeline, so
Steven Smith authored
157 times[i] = counts[i] / clock_freq;
158 free(counts);
159 summarise_samples(f, times, nr_samples);
f14f79d Try to make the log files a bit easier to parse.
Steven Smith authored
160 fclose(f);
1683c80 Move summarise_tsc_counters.c back into the main test pipeline, so
Steven Smith authored
161
162 #ifdef DUMP_RAW_TSCS
163 f = open_logfile(td, "raw_tsc");
164 for (i = 0; i < nr_samples; i++)
165 fprintf(f, "%e\n", times[i]);
166 fclose(f);
167 #endif
168
169 free(times);
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
170 }
171
ca50a42 @avsm better help message
authored
172 static void
173 help(char *argv[])
174 {
e0a16b7 Add a -n option which allows you to specify which NUMA node shared
Steven Smith authored
175 fprintf(stderr, "Usage:\n%s [-h] [-a <cpuid>] [-b <cpuid>] [-p <num] [-t] [-s <bytes>] [-c <num>] [-o <directory>] [-n <node>]\n", argv[0]);
ca50a42 @avsm better help message
authored
176 fprintf(stderr, "-h: show this help message\n");
21059a6 @avsm add option to control both parent/child (via -a -b), and a core2core scr...
authored
177 fprintf(stderr, "-a: CPU id that the first process should have affinity with\n");
178 fprintf(stderr, "-b: CPU id that the second process should have affinity with\n");
ca50a42 @avsm better help message
authored
179 fprintf(stderr, "-p: number of parallel tests to run\n");
180 fprintf(stderr, "-t: use high-res TSC to get more accurate results\n");
181 fprintf(stderr, "-s: Size of each packet\n");
182 fprintf(stderr, "-c: Number of iterations\n");
d4b7d42 Make it easier to log the results to a file for later analysis.
Steven Smith authored
183 fprintf(stderr, "-o: Where to put the various output files\n");
e0a16b7 Add a -n option which allows you to specify which NUMA node shared
Steven Smith authored
184 fprintf(stderr, "-n: NUMA node for shared arena, if any\n");
ca50a42 @avsm better help message
authored
185 exit(1);
186 }
d4b7d42 Make it easier to log the results to a file for later analysis.
Steven Smith authored
187
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
188 void
eff6ba6 Merge branch 'master' of git://github.com/avsm/ipc-bench
Steven Smith authored
189 parse_args(int argc, char *argv[], bool *per_iter_timings, int *size, size_t *count, int *first_cpu, int *second_cpu,
b75a059 Merge branch 'master' of git://github.com/avsm/ipc-bench
Steven Smith authored
190 int *parallel, char **output_dir, int *write_in_place, int *read_in_place, int *produce_method, int *do_verify,
191 int *numa_node)
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
192 {
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
193 int opt;
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
194 *per_iter_timings = false;
21059a6 @avsm add option to control both parent/child (via -a -b), and a core2core scr...
authored
195 *first_cpu = 0;
196 *second_cpu = 0;
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
197 *parallel = 1;
198 *size = 1024;
199 *count = 100;
d4b7d42 Make it easier to log the results to a file for later analysis.
Steven Smith authored
200 *output_dir = "results";
35e0e15 Fix NUMA allocation
Your Name authored
201 *numa_node = -1;
b9082c8 @smowton Restructure tests to factor out the actual 'workload', part 1
smowton authored
202 *produce_method = 0;
203 *read_in_place = 0;
204 *write_in_place = 0;
2e1109a @smowton Debug ported tested and make verify step optional
smowton authored
205 *do_verify = 0;
b75a059 Merge branch 'master' of git://github.com/avsm/ipc-bench
Steven Smith authored
206 while((opt = getopt(argc, argv, "h?tp:a:b:s:c:o:wrvm:n:")) != -1) {
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
207 switch(opt) {
208 case 't':
209 *per_iter_timings = true;
210 break;
211 case 'p':
212 *parallel = atoi(optarg);
190507d @avsm missing break
authored
213 break;
fc94026 @avsm replace -2 parameter with <-a cpuid> to make it easier to explore multic...
authored
214 case 'a':
21059a6 @avsm add option to control both parent/child (via -a -b), and a core2core scr...
authored
215 *first_cpu = atoi(optarg);
216 break;
217 case 'b':
fc94026 @avsm replace -2 parameter with <-a cpuid> to make it easier to explore multic...
authored
218 *second_cpu = atoi(optarg);
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
219 break;
220 case 's':
221 *size = atoi(optarg);
222 break;
223 case 'c':
224 *count = atoi(optarg);
225 break;
d4b7d42 Make it easier to log the results to a file for later analysis.
Steven Smith authored
226 case 'o':
227 *output_dir = optarg;
228 break;
9ff1b7b @smowton Add support for optional writing of actual data, plus actual support fro...
smowton authored
229 case 'm':
b9082c8 @smowton Restructure tests to factor out the actual 'workload', part 1
smowton authored
230 *produce_method = atoi(optarg);
231 break;
232 case 'r':
233 *read_in_place = 1;
234 break;
235 case 'w':
236 *write_in_place = 1;
9ff1b7b @smowton Add support for optional writing of actual data, plus actual support fro...
smowton authored
237 break;
2e1109a @smowton Debug ported tested and make verify step optional
smowton authored
238 case 'v':
239 *do_verify = 1;
9ff1b7b @smowton Add support for optional writing of actual data, plus actual support fro...
smowton authored
240 break;
e0a16b7 Add a -n option which allows you to specify which NUMA node shared
Steven Smith authored
241 case 'n':
242 *numa_node = atoi(optarg);
243 break;
ca50a42 @avsm better help message
authored
244 case '?':
245 case 'h':
246 help(argv);
247 default:
248 fprintf(stderr, "unknown command-line option '%c'", opt);
249 help(argv);
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
250 }
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
251 }
b9082c8 @smowton Restructure tests to factor out the actual 'workload', part 1
smowton authored
252
400a8db @avsm guard affinity and numa shm establishment as linux-specific functions
authored
253 fprintf(stderr, "size %d count %" PRIu64 " first_cpu %d second_cpu %d parallel %d tsc %d produce-method %d %s %s numa_node %d output_dir %s\n",
b9082c8 @smowton Restructure tests to factor out the actual 'workload', part 1
smowton authored
254 *size, *count, *first_cpu, *second_cpu, *parallel, *per_iter_timings, *produce_method, *read_in_place ? "read-in-place" : "copy-read", *write_in_place ? "write-in-place" : "copy-write",
b75a059 Merge branch 'master' of git://github.com/avsm/ipc-bench
Steven Smith authored
255 *numa_node,
eff6ba6 Merge branch 'master' of git://github.com/avsm/ipc-bench
Steven Smith authored
256 *output_dir);
d2e837c Track how long each iteration takes, and then try to do some simple
Steven Smith authored
257 }
cb7e4c5 Merge branch 'master' of git://github.com/avsm/ipc-bench
Steven Smith authored
258
4f9900f @avsm rewrite test runner to support multiple parallel tests to simulate load
authored
259 void
f9eb624 @avsm add xfork() to control pinning the affinity of forked processes (via SEP...
authored
260 setaffinity(int cpunum)
261 {
400a8db @avsm guard affinity and numa shm establishment as linux-specific functions
authored
262 #ifdef Linux
f9eb624 @avsm add xfork() to control pinning the affinity of forked processes (via SEP...
authored
263 cpu_set_t *mask;
264 size_t size;
265 int i;
316b1d7 Make the sched_setaffinity business work on machines with more than 48
Steven Smith authored
266 int nrcpus = 160;
f9eb624 @avsm add xfork() to control pinning the affinity of forked processes (via SEP...
authored
267 pid_t pid;
268 mask = CPU_ALLOC(nrcpus);
269 size = CPU_ALLOC_SIZE(nrcpus);
270 CPU_ZERO_S(size, mask);
271 CPU_SET_S(cpunum, size, mask);
272 pid = getpid();
273 i = sched_setaffinity(pid, size, mask);
274 if (i == -1)
275 err(1, "sched_setaffinity");
276 CPU_FREE(mask);
400a8db @avsm guard affinity and numa shm establishment as linux-specific functions
authored
277 #else
278 fprintf(stderr, "setaffinity: skipping\n");
279 #endif
f9eb624 @avsm add xfork() to control pinning the affinity of forked processes (via SEP...
authored
280 }
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
281
400a8db @avsm guard affinity and numa shm establishment as linux-specific functions
authored
282 #ifdef Linux
283 #include <numa.h>
284 #endif
285
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
286 void *
e0a16b7 Add a -n option which allows you to specify which NUMA node shared
Steven Smith authored
287 establish_shm_segment(int nr_pages, int numa_node)
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
288 {
400a8db @avsm guard affinity and numa shm establishment as linux-specific functions
authored
289 #ifdef Linux
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
290 int fd;
291 void *addr;
e0a16b7 Add a -n option which allows you to specify which NUMA node shared
Steven Smith authored
292
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
293 fd = shm_open("/memflag_lat", O_RDWR|O_CREAT|O_EXCL, 0600);
294 if (fd < 0)
295 err(1, "shm_open(\"/memflag_lat\")");
296 shm_unlink("/memflag_lat");
297 if (ftruncate(fd, PAGE_SIZE * nr_pages) < 0)
298 err(1, "ftruncate() shared memory segment");
299 addr = mmap(NULL, PAGE_SIZE * nr_pages, PROT_READ|PROT_WRITE, MAP_SHARED,
300 fd, 0);
301 if (addr == MAP_FAILED)
302 err(1, "mapping shared memory segment");
303
35e0e15 Fix NUMA allocation
Your Name authored
304 if(numa_node != -1)
305 numa_tonode_memory(addr, PAGE_SIZE * nr_pages, numa_node);
306
307 close(fd);
e0a16b7 Add a -n option which allows you to specify which NUMA node shared
Steven Smith authored
308
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
309 return addr;
400a8db @avsm guard affinity and numa shm establishment as linux-specific functions
authored
310 #else
311 errx(1, "establish_shm_segment not implemented\n");
312 #endif
985fdd0 Simple in-memory IPC throughput test.
Steven Smith authored
313 }
f14f79d Try to make the log files a bit easier to parse.
Steven Smith authored
314
315 void
316 logmsg(test_data *td, const char *file, const char *fmt, ...)
317 {
318 FILE *f = open_logfile(td, file);
319 va_list args;
320 char *res;
321
322 va_start(args, fmt);
323 if (vasprintf(&res, fmt, args) < 0)
324 err(1, "vasprintf(%s)", fmt);
325 va_end(args);
326
327 if (fputs(res, f) == EOF)
328 err(1, "fputs(%s) to logfile:%s", res, file);
329
330 if (fclose(f) == EOF)
331 err(1, "fclose(logfile:%s)", file);
332 }
Something went wrong with that request. Please try again.