Changes in / [badd22f:4c925cd]
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/benchcltr.hfa
rbadd22f r4c925cd 1 1 #pragma once 2 #include <assert.h> 3 #include <stdint.h> 2 4 3 #include <assert.h> 4 #include <kernel.hfa> 5 #include <thread.hfa> 6 #include <stats.hfa> 5 #ifdef __cforall 6 #include <kernel.hfa> 7 #include <thread.hfa> 8 #include <stats.hfa> 9 #else 10 #include <time.h> // timespec 11 #include <sys/time.h> // timeval 12 13 enum { TIMEGRAN = 1000000000LL }; // nanosecond granularity, except for timeval 14 #endif 7 15 8 16 #define BENCH_OPT_SHORT "d:p:t:SPV" … … 14 22 {"procstat", no_argument , 0, 'P'}, \ 15 23 {"viewhalts", no_argument , 0, 'V'}, 16 17 #define BENCH_DECL \18 double duration = 5; \19 int nprocs = 1; \20 int nthreads = 1;21 24 22 25 #define BENCH_OPT_CASE \ … … 52 55 break; 53 56 57 double duration = 5; 58 int nprocs = 1; 59 int nthreads = 1; 54 60 bool silent = false; 61 bool continuous = false; 55 62 bool procstats = false; 56 63 bool viewhalts = false; 64 65 #define BENCH_OPT_CFA \ 66 {'d', "duration", "Duration of the experiments in seconds", duration }, \ 67 {'t', "nthreads", "Number of threads to use", nthreads }, \ 68 {'p', "nprocs", "Number of processors to use", nprocs }, \ 69 {'S', "nostats", "Don't print statistics", silent, parse_settrue }, \ 70 {'C', "constats", "Regularly print statistics", continuous, parse_settrue }, \ 71 {'P', "procstat", "Print statistics for each processors", procstats, parse_settrue }, \ 72 {'V', "viewhalts", "Visualize halts, prints timestamp and Processor id for each halt.", viewhalts, parse_settrue }, 73 74 #ifdef __cforall 75 #include <parseargs.hfa> 76 57 77 struct cluster * the_benchmark_cluster = 0p; 58 78 struct BenchCluster { … … 60 80 }; 61 81 62 void ?{}( BenchCluster & this, int flags, int stats ) {63 (this.self){ "Benchmark Cluster", flags };82 void ?{}( BenchCluster & this, int num_io, const io_context_params & io_params, int stats ) { 83 (this.self){ "Benchmark Cluster", num_io, io_params }; 64 84 65 85 assert( the_benchmark_cluster == 0p ); … … 105 125 } 106 126 } 127 #else 128 uint64_t getTimeNsec() { 129 timespec curr; 130 clock_gettime( CLOCK_REALTIME, &curr ); 131 return (int64_t)curr.tv_sec * TIMEGRAN + curr.tv_nsec; 132 } 133 134 uint64_t to_miliseconds( uint64_t durtn ) { return durtn / (TIMEGRAN / 1000LL); } 135 double to_fseconds(uint64_t durtn ) { return durtn / (double)TIMEGRAN; } 136 uint64_t from_fseconds(double sec) { return sec * TIMEGRAN; } 137 138 139 void wait_duration(double duration, uint64_t & start, uint64_t & end, bool is_tty) { 140 for(;;) { 141 usleep(100000); 142 end = getTimeNsec(); 143 uint64_t delta = end - start; 144 /*if(is_tty)*/ { 145 printf(" %.1f\r", to_fseconds(delta)); 146 fflush(stdout); 147 } 148 if( delta >= from_fseconds(duration) ) { 149 break; 150 } 151 } 152 } 153 #endif 154 107 155 108 156 void bench_usage( char * argv [] ) { -
benchmark/io/readv.cfa
rbadd22f r4c925cd 40 40 int do_read(int fd, struct iovec * iov) { 41 41 // extern ssize_t cfa_preadv2(int, const struct iovec *, int, off_t, int, int = 0, Duration = -1`s, io_cancellation * = 0p, io_context * = 0p); 42 int sflags = 0; 42 int sflags = 0 43 #if defined(CFA_HAVE_IOSQE_ASYNC) 44 | CFA_IO_ASYNC 45 #else 46 #warning no CFA_IO_ASYNC support 47 #endif 48 ; 43 49 if(fixed_file) { 44 50 sflags |= CFA_IO_FIXED_FD1; … … 63 69 64 70 int main(int argc, char * argv[]) { 65 BENCH_DECL71 int file_flags = 0; 66 72 unsigned num_io = 1; 67 io_context_params params;68 int file_flags = 0;69 73 unsigned sublen = 16; 74 unsigned nentries = 0; 70 75 71 arg_loop: 72 for(;;) { 73 static struct option options[] = { 74 BENCH_OPT_LONG 75 {"bufsize", required_argument, 0, 'b'}, 76 {"submitthread", no_argument , 0, 's'}, 77 {"eagersubmit", no_argument , 0, 'e'}, 78 {"kpollsubmit", no_argument , 0, 'k'}, 79 {"kpollcomplete", no_argument , 0, 'i'}, 80 {"fixed-files", no_argument , 0, 'f'}, 81 {"open-direct", no_argument , 0, 'o'}, 82 {"submitlength", required_argument, 0, 'l'}, 83 {0, 0, 0, 0} 84 }; 76 bool subthrd = false; 77 bool subeagr = false; 78 bool odirect = false; 79 bool kpollsb = false; 80 bool kpollcp = false; 85 81 86 int idx = 0; 87 int opt = getopt_long(argc, argv, BENCH_OPT_SHORT "b:sekil:", options, &idx); 82 cfa_option opt[] = { 83 BENCH_OPT_CFA 84 {'b', "bufsize", "Number of bytes to read per request", buflen}, 85 {'s', "submitthread", "If set, cluster uses polling thread to submit I/O", subthrd, parse_settrue}, 86 {'e', "eagersubmit", "If set, cluster submits I/O eagerly but still aggregates submits", subeagr, parse_settrue}, 87 {'f', "fixed-files", "Pre-register files with the io_contexts", fixed_file, parse_settrue}, 88 {'o', "open-direct", "Open files with O_DIRECT flag, bypassing the file cache", odirect, parse_settrue}, 89 {'k', "kpollsubmit", "If set, cluster uses an in kernel thread to poll submission, implies -f, requires elevated permissions", kpollsb, parse_settrue}, 90 {'i', "kpollcomplete", "If set, cluster polls fds for completions instead of relying on interrupts to get notifications, implies -o", kpollcp, parse_settrue}, 91 {'l', "submitlength", "Size of the buffer that stores ready submissions", sublen}, 92 {'r', "numentries", "Number of entries each of the io_context have", nentries}, 93 {'n', "numcontexts", "Number of io_contexts to the cluster", num_io}, 94 }; 95 int opt_cnt = sizeof(opt) / sizeof(cfa_option); 88 96 89 const char * arg = optarg ? optarg : ""; 90 char * end; 91 switch(opt) { 92 // Exit Case 93 case -1: 94 break arg_loop; 95 BENCH_OPT_CASE 96 case 'b': 97 buflen = strtoul(arg, &end, 10); 98 if(*end != '\0' && buflen < 10) { 99 fprintf(stderr, "Buffer size must be at least 10, was %s\n", arg); 100 goto usage; 101 } 102 break; 103 case 's': 104 params.poller_submits = true; 105 break; 106 case 'e': 107 params.eager_submits = true; 108 break; 109 case 'k': 110 params.poll_submit = true; 111 case 'f': 112 fixed_file = true; 113 break; 114 case 'i': 115 params.poll_complete = true; 116 case 'o': 117 file_flags |= O_DIRECT; 118 break; 119 case 'l': 120 sublen = strtoul(arg, &end, 10); 121 if(*end != '\0' && sublen < 16) { 122 fprintf(stderr, "Submit length must be at least 16, was %s\n", arg); 123 goto usage; 124 } 125 // flags |= (sublen << CFA_CLUSTER_IO_BUFFLEN_OFFSET); 126 break; 127 default: /* ? */ 128 fprintf(stderr, "%d\n", opt); 129 usage: 130 bench_usage( argv ); 131 fprintf( stderr, " -b, --buflen=SIZE Number of bytes to read per request\n" ); 132 fprintf( stderr, " -u, --userthread If set, cluster uses user-thread to poll I/O\n" ); 133 fprintf( stderr, " -s, --submitthread If set, cluster uses polling thread to submit I/O\n" ); 134 fprintf( stderr, " -e, --eagersubmit If set, cluster submits I/O eagerly but still aggregates submits\n" ); 135 fprintf( stderr, " -k, --kpollsubmit If set, cluster uses IORING_SETUP_SQPOLL\n" ); 136 fprintf( stderr, " -i, --kpollcomplete If set, cluster uses IORING_SETUP_IOPOLL\n" ); 137 fprintf( stderr, " -l, --submitlength=LEN Max number of submitions that can be submitted together\n" ); 138 exit(EXIT_FAILURE); 97 char **left; 98 parse_args( opt, opt_cnt, "[OPTIONS]...\ncforall yield benchmark", left ); 99 100 if(kpollcp || odirect) { 101 if( (buflen % 512) != 0 ) { 102 fprintf(stderr, "Buffer length must be a multiple of 512 when using O_DIRECT, was %lu\n\n", buflen); 103 print_args_usage(opt, opt_cnt, "[OPTIONS]...\ncforall yield benchmark", true); 139 104 } 140 105 } 106 107 io_context_params params; 108 109 if( subthrd ) params.poller_submits = true; 110 if( subeagr ) params.eager_submits = true; 111 if( kpollsb ) params.poll_submit = true; 112 if( kpollcp ) params.poll_complete = true; 113 114 if(params.poll_submit ) fixed_file = true; 115 if(params.poll_complete) odirect = true; 116 117 params.num_ready = sublen; 118 params.num_entries = nentries; 119 120 if(odirect) file_flags |= O_DIRECT; 141 121 142 122 int lfd = open(__FILE__, file_flags); -
benchmark/readyQ/yield.cfa
rbadd22f r4c925cd 43 43 44 44 int main(int argc, char * argv[]) { 45 BENCH_DECL 45 unsigned num_io = 1; 46 io_context_params params; 46 47 47 for(;;) { 48 static struct option options[] = { 49 BENCH_OPT_LONG 50 {0, 0, 0, 0} 51 }; 48 cfa_option opt[] = { 49 BENCH_OPT_CFA 50 }; 51 int opt_cnt = sizeof(opt) / sizeof(cfa_option); 52 52 53 int idx = 0; 54 int opt = getopt_long(argc, argv, BENCH_OPT_SHORT, options, &idx); 55 56 const char * arg = optarg ? optarg : ""; 57 char * end; 58 switch(opt) { 59 case -1: 60 goto run; 61 BENCH_OPT_CASE 62 default: /* ? */ 63 fprintf( stderr, "Unkown option '%c'\n", opt); 64 usage: 65 bench_usage( argv ); 66 exit(1); 67 } 68 } 69 run: 53 char **left; 54 parse_args( argc, argv, opt, opt_cnt, "[OPTIONS]...\ncforall yield benchmark", left ); 70 55 71 56 { … … 73 58 74 59 Time start, end; 75 BenchCluster cl = { 0, CFA_STATS_READY_Q };60 BenchCluster cl = { num_io, params, CFA_STATS_READY_Q }; 76 61 { 77 62 BenchProc procs[nprocs]; -
libcfa/src/concurrency/io.cfa
rbadd22f r4c925cd 359 359 360 360 // We got the lock 361 // Collect the submissions 361 362 unsigned to_submit = __collect_submitions( ring ); 363 364 // Actually submit 362 365 int ret = __io_uring_enter( ring, to_submit, false ); 363 if( ret < 0 ) { 364 unlock(ring.submit_q.lock); 365 return; 366 } 367 368 /* paranoid */ verify( ret > 0 || to_submit == 0 || (ring.ring_flags & IORING_SETUP_SQPOLL) ); 366 367 unlock(ring.submit_q.lock); 368 if( ret < 0 ) return; 369 369 370 370 // Release the consumed SQEs … … 372 372 373 373 // update statistics 374 __STATS__( true,374 __STATS__( false, 375 375 io.submit_q.submit_avg.rdy += to_submit; 376 376 io.submit_q.submit_avg.csm += ret; 377 377 io.submit_q.submit_avg.cnt += 1; 378 378 ) 379 380 unlock(ring.submit_q.lock);381 379 } 382 380 else { -
libcfa/src/concurrency/io/setup.cfa
rbadd22f r4c925cd 298 298 if( params_in.poll_complete ) params.flags |= IORING_SETUP_IOPOLL; 299 299 300 uint32_t nentries = params_in.num_entries; 300 uint32_t nentries = params_in.num_entries != 0 ? params_in.num_entries : 256; 301 if( !is_pow2(nentries) ) { 302 abort("ERROR: I/O setup 'num_entries' must be a power of 2\n"); 303 } 304 if( params_in.poller_submits && params_in.eager_submits ) { 305 abort("ERROR: I/O setup 'poller_submits' and 'eager_submits' cannot be used together\n"); 306 } 301 307 302 308 int fd = syscall(__NR_io_uring_setup, nentries, ¶ms ); -
libcfa/src/concurrency/iocall.cfa
rbadd22f r4c925cd 101 101 #endif 102 102 103 104 103 #define __submit_prelude \ 105 104 if( 0 != (submit_flags & LINK_FLAGS) ) { errno = ENOTSUP; return -1; } \ … … 110 109 struct io_uring_sqe * sqe; \ 111 110 uint32_t idx; \ 111 uint8_t sflags = REGULAR_FLAGS & submit_flags; \ 112 112 [sqe, idx] = __submit_alloc( ring, (uint64_t)(uintptr_t)&data ); \ 113 sqe->flags = REGULAR_FLAGS & submit_flags;113 sqe->flags = sflags; 114 114 115 115 #define __submit_wait \ … … 186 186 __submit_prelude 187 187 188 (*sqe){ IORING_OP_READV, fd, iov, iovcnt, offset }; 188 sqe->opcode = IORING_OP_READV; 189 sqe->ioprio = 0; 190 sqe->fd = fd; 191 sqe->off = offset; 192 sqe->addr = (uint64_t)(uintptr_t)iov; 193 sqe->len = iovcnt; 194 sqe->rw_flags = 0; 195 sqe->__pad2[0] = sqe->__pad2[1] = sqe->__pad2[2] = 0; 189 196 190 197 __submit_wait -
libcfa/src/parseargs.cfa
rbadd22f r4c925cd 19 19 extern long long int strtoll (const char* str, char** endptr, int base); 20 20 extern unsigned long long int strtoull(const char* str, char** endptr, int base); 21 extern double strtod (const char* str, char** endptr); 21 22 } 22 23 … … 28 29 extern char ** cfa_args_envp; 29 30 30 void printopt(FILE * out, int width, int max, char sn, const char * ln, const char * help) { 31 int hwidth = max - (11 + width); 32 if(hwidth <= 0) hwidth = max; 33 34 fprintf(out, " -%c, --%-*s %.*s\n", sn, width, ln, hwidth, help); 35 for() { 36 help += min(strlen(help), hwidth); 37 if('\0' == *help) break; 38 fprintf(out, "%*s%.*s\n", width + 11, "", hwidth, help); 39 } 40 } 31 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out) __attribute__ ((noreturn)); 41 32 42 33 void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) { … … 44 35 } 45 36 37 //----------------------------------------------------------------------------- 38 // getopt_long wrapping 46 39 void parse_args( 47 40 int argc, … … 53 46 ) { 54 47 struct option optarr[opt_count + 2]; 55 int width = 0;56 int max_width = 1_000_000;57 48 { 58 49 int idx = 0; … … 69 60 } 70 61 idx++; 71 72 int w = strlen(options[i].long_name);73 if(w > width) width = w;74 62 } 75 63 } … … 106 94 out = stdout; 107 95 case '?': 108 goto USAGE;96 usage(argv[0], options, opt_count, usage, out); 109 97 default: 110 98 for(i; opt_count) { … … 115 103 116 104 fprintf(out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt); 117 goto USAGE;105 usage(argv[0], options, opt_count, usage, out); 118 106 } 119 107 } … … 122 110 123 111 } 124 125 USAGE:; 112 } 113 114 //----------------------------------------------------------------------------- 115 // Print usage 116 static void printopt(FILE * out, int width, int max, char sn, const char * ln, const char * help) { 117 int hwidth = max - (11 + width); 118 if(hwidth <= 0) hwidth = max; 119 120 fprintf(out, " -%c, --%-*s %.*s\n", sn, width, ln, hwidth, help); 121 for() { 122 help += min(strlen(help), hwidth); 123 if('\0' == *help) break; 124 fprintf(out, "%*s%.*s\n", width + 11, "", hwidth, help); 125 } 126 } 127 128 void print_args_usage(cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)) { 129 usage(cfa_args_argv[0], options, opt_count, usage, error ? stderr : stdout); 130 } 131 132 void print_args_usage(int , char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)) { 133 usage(argv[0], options, opt_count, usage, error ? stderr : stdout); 134 } 135 136 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * help, FILE * out) __attribute__((noreturn)) { 137 int width = 0; 138 { 139 int idx = 0; 140 for(i; opt_count) { 141 if(options[i].long_name) { 142 int w = strlen(options[i].long_name); 143 if(w > width) width = w; 144 } 145 } 146 } 147 148 int max_width = 1_000_000; 126 149 int outfd = fileno(out); 127 150 if(isatty(outfd)) { … … 132 155 } 133 156 134 fprintf(out, "Usage:\n %s %s\n", argv[0], usage);157 fprintf(out, "Usage:\n %s %s\n", cmd, help); 135 158 136 159 for(i; opt_count) { … … 141 164 } 142 165 166 //----------------------------------------------------------------------------- 167 // Typed argument parsing 143 168 bool parse_yesno(const char * arg, bool & value ) { 144 169 if(strcmp(arg, "yes") == 0) { … … 167 192 bool parse(const char * arg, const char * & value ) { 168 193 value = arg; 194 return true; 195 } 196 197 bool parse(const char * arg, int & value) { 198 char * end; 199 int r = strtoll(arg, &end, 10); 200 if(*end != '\0') return false; 201 202 value = r; 169 203 return true; 170 204 } … … 200 234 } 201 235 202 bool parse(const char * arg, int& value) {203 char * end; 204 int r = strtoll(arg, &end, 10);205 if(*end != '\0') return false; 206 207 value = r; 208 return true; 209 } 236 bool parse(const char * arg, double & value) { 237 char * end; 238 double r = strtod(arg, &end); 239 if(*end != '\0') return false; 240 241 value = r; 242 return true; 243 } -
libcfa/src/parseargs.hfa
rbadd22f r4c925cd 34 34 void parse_args( int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, char ** & left ); 35 35 36 void print_args_usage(cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)); 37 void print_args_usage(int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error) __attribute__ ((noreturn)); 38 36 39 bool parse_yesno (const char *, bool & ); 37 40 bool parse_settrue (const char *, bool & ); … … 39 42 40 43 bool parse(const char *, const char * & ); 44 bool parse(const char *, int & ); 41 45 bool parse(const char *, unsigned & ); 42 46 bool parse(const char *, unsigned long & ); 43 47 bool parse(const char *, unsigned long long & ); 44 bool parse(const char *, int& );48 bool parse(const char *, double & );
Note: See TracChangeset
for help on using the changeset viewer.