source: benchmark/readyQ/rq_bench.hpp@ d23c0b2

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since d23c0b2 was c4241b6, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Minor benchmark fixes and added locality implementation for libfibre

  • Property mode set to 100644
File size: 9.5 KB
Line 
1#include <cassert>
2#include <climits>
3#include <cstdint>
4#include <cstdio>
5
6#include <time.h> // timespec
7#include <sys/time.h> // timeval
8
9enum { TIMEGRAN = 1000000000LL }; // nanosecond granularity, except for timeval
10
11
12volatile bool stop = false;
13bool clock_mode;
14double duration = -1;
15unsigned long long stop_count = 0;
16unsigned nprocs = 1;
17unsigned nthreads = 1;
18
19volatile unsigned long long threads_left;
20
21#define BENCH_OPT \
22 {'d', "duration", "Duration of the experiments in seconds", duration }, \
23 {'i', "iterations", "Number of iterations of the experiments", stop_count }, \
24 {'t', "nthreads", "Number of threads to use", nthreads }, \
25 {'p', "nprocs", "Number of processors to use", nprocs }
26
27#define BENCH_OPT_PARSE(name) \
28 { \
29 int opt_cnt = sizeof(opt) / sizeof(option_t); \
30 char **left; \
31 parse_args( argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, &left ); \
32 if(duration > 0 && stop_count > 0) { \
33 fprintf(stderr, "--duration and --iterations cannot be used together\n"); \
34 print_args_usage(argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, true); \
35 } else if(duration > 0) { \
36 clock_mode = true; \
37 stop_count = 0xFFFFFFFFFFFFFFFF; \
38 printf("Running for %lf seconds\n", duration); \
39 } else if(stop_count > 0) { \
40 clock_mode = false; \
41 printf("Running for %llu iterations\n", stop_count); \
42 } else { \
43 duration = 5; clock_mode = true;\
44 printf("Running for %lf seconds\n", duration); \
45 } \
46 }
47
48uint64_t getTimeNsec() {
49 timespec curr;
50 clock_gettime( CLOCK_REALTIME, &curr );
51 return (int64_t)curr.tv_sec * TIMEGRAN + curr.tv_nsec;
52}
53
54uint64_t to_miliseconds( uint64_t durtn ) { return durtn / (TIMEGRAN / 1000LL); }
55double to_fseconds(uint64_t durtn ) { return durtn / (double)TIMEGRAN; }
56uint64_t from_fseconds(double sec) { return sec * TIMEGRAN; }
57
58template<typename Sleeper>
59void wait(const uint64_t & start, bool is_tty) {
60 for(;;) {
61 Sleeper::usleep(100000);
62 uint64_t end = getTimeNsec();
63 uint64_t delta = end - start;
64 if(is_tty) {
65 printf(" %.1f\r", to_fseconds(delta));
66 fflush(stdout);
67 }
68 if( clock_mode && delta >= from_fseconds(duration) ) {
69 break;
70 }
71 else if( !clock_mode && threads_left == 0 ) {
72 break;
73 }
74 }
75}
76
77// ==========================================================================================
78#include <cstdlib>
79#include <cstring>
80
81#include <algorithm>
82
83//-----------------------------------------------------------------------------
84// Typed argument parsing
85bool parse_yesno(const char * arg, bool & value ) {
86 if(strcmp(arg, "yes") == 0) {
87 value = true;
88 return true;
89 }
90
91 if(strcmp(arg, "no") == 0) {
92 value = false;
93 return true;
94 }
95
96 return false;
97}
98
99bool parse_truefalse(const char * arg, bool & value) {
100 if(strcmp(arg, "true") == 0) {
101 value = true;
102 return true;
103 }
104
105 if(strcmp(arg, "false") == 0) {
106 value = false;
107 return true;
108 }
109
110 return false;
111}
112
113bool parse_settrue (const char *, bool & value ) {
114 value = true;
115 return true;
116}
117
118bool parse_setfalse(const char *, bool & value ) {
119 value = false;
120 return true;
121}
122
123bool parse(const char * arg, const char * & value ) {
124 value = arg;
125 return true;
126}
127
128bool parse(const char * arg, int & value) {
129 char * end;
130 int r = strtoll(arg, &end, 10);
131 if(*end != '\0') return false;
132
133 value = r;
134 return true;
135}
136
137bool parse(const char * arg, unsigned & value) {
138 char * end;
139 unsigned long long int r = strtoull(arg, &end, 10);
140 if(*end != '\0') return false;
141 if(r > UINT_MAX) return false;
142
143 value = r;
144 return true;
145}
146
147bool parse(const char * arg, unsigned long & value) {
148 char * end;
149 unsigned long long int r = strtoull(arg, &end, 10);
150 if(*end != '\0') return false;
151 if(r > ULONG_MAX) return false;
152
153 value = r;
154 return true;
155}
156
157bool parse(const char * arg, unsigned long long & value) {
158 char * end;
159 unsigned long long int r = strtoull(arg, &end, 10);
160 if(*end != '\0') return false;
161 if(r > ULLONG_MAX) return false;
162
163 value = r;
164 return true;
165}
166
167bool parse(const char * arg, double & value) {
168 char * end;
169 double r = strtod(arg, &end);
170 if(*end != '\0') return false;
171
172 value = r;
173 return true;
174}
175
176//-----------------------------------------------------------------------------
177struct option_t {
178 char short_name;
179 const char * long_name;
180 const char * help;
181 void * variable;
182 bool (*parse_fun)(const char *, void * );
183
184 template<typename T>
185 inline option_t( char short_name, const char * long_name, const char * help, T & variable ) {
186 this->short_name = short_name;
187 this->long_name = long_name;
188 this->help = help;
189 this->variable = reinterpret_cast<void*>(&variable);
190 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(static_cast<bool (*)(const char *, T & )>(parse));
191 }
192
193 template<typename T>
194 inline option_t( char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) {
195 this->short_name = short_name;
196 this->long_name = long_name;
197 this->help = help;
198 this->variable = reinterpret_cast<void*>(&variable);
199 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(parse);
200 }
201};
202
203extern option_t last_option;
204
205
206//-----------------------------------------------------------------------------
207#include <cstdint>
208#include <climits>
209#include <errno.h>
210#include <unistd.h>
211extern "C" {
212 #include <getopt.h>
213 #include <sys/ioctl.h>
214
215 extern FILE * stderr;
216 extern FILE * stdout;
217
218 extern int fileno(FILE *stream);
219
220 extern int fprintf ( FILE * stream, const char * format, ... );
221
222 extern long long int strtoll (const char* str, char** endptr, int base);
223 extern unsigned long long int strtoull(const char* str, char** endptr, int base);
224 extern double strtod (const char* str, char** endptr);
225}
226
227static void usage(char * cmd, option_t options[], size_t opt_count, const char * usage, FILE * out) __attribute__ ((noreturn));
228
229//-----------------------------------------------------------------------------
230// getopt_long wrapping
231void parse_args(
232 int argc,
233 char * argv[],
234 option_t options[],
235 size_t opt_count,
236 const char * usage_msg,
237 char ** * left
238) {
239 struct option optarr[opt_count + 2];
240 {
241 int idx = 0;
242 for(size_t i = 0; i < opt_count; i++) {
243 if(options[i].long_name) {
244 optarr[idx].name = options[i].long_name;
245 optarr[idx].flag = nullptr;
246 optarr[idx].val = options[i].short_name;
247 if( ((intptr_t)options[i].parse_fun) == ((intptr_t)parse_settrue)
248 || ((intptr_t)options[i].parse_fun) == ((intptr_t)parse_setfalse) ) {
249 optarr[idx].has_arg = no_argument;
250 } else {
251 optarr[idx].has_arg = required_argument;
252 }
253 idx++;
254 }
255 }
256 optarr[idx+0].name = "help";
257 optarr[idx+0].has_arg = no_argument;
258 optarr[idx+0].flag = 0;
259 optarr[idx+0].val = 'h';
260 optarr[idx+1].name = 0;
261 optarr[idx+1].has_arg = no_argument;
262 optarr[idx+1].flag = 0;
263 optarr[idx+1].val = 0;
264 }
265
266 char optstring[opt_count * 3];
267 for(auto & o : optstring) {
268 o = '\0';
269 }
270 {
271 int idx = 0;
272 for(size_t i = 0; i < opt_count; i++) {
273 optstring[idx] = options[i].short_name;
274 idx++;
275 if( ((intptr_t)options[i].parse_fun) != ((intptr_t)parse_settrue)
276 && ((intptr_t)options[i].parse_fun) != ((intptr_t)parse_setfalse) ) {
277 optstring[idx] = ':';
278 idx++;
279 }
280 }
281 optstring[idx+0] = 'h';
282 optstring[idx+1] = '\0';
283 }
284
285 FILE * out = stderr;
286 for(;;) {
287 int idx = 0;
288 int opt = getopt_long(argc, argv, optstring, optarr, &idx);
289 switch(opt) {
290 case -1:
291 if(left != nullptr) *left = argv + optind;
292 return;
293 case 'h':
294 out = stdout;
295 [[fallthrough]];
296 case '?':
297 usage(argv[0], options, opt_count, usage_msg, out);
298 default:
299 for(size_t i = 0; i < opt_count; i++) {
300 if(opt == options[i].short_name) {
301 const char * arg = optarg ? optarg : "";
302 if( arg[0] == '=' ) { arg++; }
303 bool success = options[i].parse_fun( arg, options[i].variable );
304 if(success) goto NEXT_ARG;
305
306 fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt);
307 usage(argv[0], options, opt_count, usage_msg, out);
308 }
309 }
310 std::abort();
311 }
312 NEXT_ARG:;
313 }
314}
315
316//-----------------------------------------------------------------------------
317// Print usage
318static void printopt(FILE * out, int width, int max, char sn, const char * ln, const char * help) {
319 int hwidth = max - (11 + width);
320 if(hwidth <= 0) hwidth = max;
321
322 fprintf(out, " -%c, --%-*s %.*s\n", sn, width, ln, hwidth, help);
323 for(;;) {
324 help += std::min(strlen(help), (unsigned long)hwidth);
325 if('\0' == *help) break;
326 fprintf(out, "%*s%.*s\n", width + 11, "", hwidth, help);
327 }
328}
329
330__attribute__((noreturn)) void print_args_usage(int , char * argv[], option_t options[], size_t opt_count, const char * usage_msg, bool error) {
331 usage(argv[0], options, opt_count, usage_msg, error ? stderr : stdout);
332}
333
334static __attribute__((noreturn)) void usage(char * cmd, option_t options[], size_t opt_count, const char * help, FILE * out) {
335 int width = 0;
336 {
337 for(size_t i = 0; i < opt_count; i++) {
338 if(options[i].long_name) {
339 int w = strlen(options[i].long_name);
340 if(w > width) width = w;
341 }
342 }
343 }
344
345 int max_width = 1000000;
346 int outfd = fileno(out);
347 if(isatty(outfd)) {
348 struct winsize size;
349 int ret = ioctl(outfd, TIOCGWINSZ, &size);
350 if(ret < 0) abort(); // "ioctl error: (%d) %s\n", (int)errno, strerror(errno)
351 max_width = size.ws_col;
352 }
353
354 fprintf(out, "Usage:\n %s %s\n", cmd, help);
355
356 for(size_t i = 0; i < opt_count; i++) {
357 printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
358 }
359 fprintf(out, " -%c, --%-*s %s\n", 'h', width, "help", "print this help message");
360 exit(out == stdout ? 0 : 1);
361}
362
Note: See TracBrowser for help on using the repository browser.