source: benchmark/readyQ/rq_bench.hpp @ 52f6250

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 52f6250 was c4241b6, checked in by Thierry Delisle <tdelisle@…>, 4 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.