Changeset 7554e41 in mainline for uspace/app/rcubench/rcubench.c
- Timestamp:
- 2012-12-04T19:36:10Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f74ec77
- Parents:
- af5dfa5b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/rcubench/rcubench.c
raf5dfa5b r7554e41 50 50 #include <rcu.h> 51 51 52 53 /* Results are printed to this file in addition to stdout. */ 54 static FILE *results_fd = NULL; 55 52 56 typedef struct bench { 53 enum { 54 T_KERN_FUTEX, 55 T_LIBC_FUTEX 56 } type; 57 const char *name; 58 void (*func)(struct bench *); 57 59 size_t iters; 58 60 size_t nthreads; … … 61 63 futex_t done_threads; 62 64 63 futex_t ke_bench_fut; 64 fibril_mutex_t libc_bench_mtx; 65 futex_t bench_fut; 65 66 } bench_t; 66 67 … … 82 83 static void kernel_futex_bench(bench_t *bench) 83 84 { 84 futex_t * const fut = &bench-> ke_bench_fut;85 futex_t * const fut = &bench->bench_fut; 85 86 const size_t iters = bench->iters; 86 87 size_t sum = 0; … … 107 108 } 108 109 109 static void libc_futex_bench(bench_t *bench) 110 { 111 fibril_mutex_t * const mtx = &bench->libc_bench_mtx; 110 static void libc_futex_lock_bench(bench_t *bench) 111 { 112 112 const size_t iters = bench->iters; 113 futex_t loc_fut = FUTEX_INITIALIZER; 113 114 114 115 for (size_t i = 0; i < iters; ++i) { 115 f ibril_mutex_lock(mtx);116 futex_lock(&loc_fut); 116 117 /* no-op */ 117 118 compiler_barrier(); 118 fibril_mutex_unlock(mtx); 119 } 120 } 121 119 futex_unlock(&loc_fut); 120 } 121 } 122 123 static void libc_futex_sema_bench(bench_t *bench) 124 { 125 const size_t iters = bench->iters; 126 futex_t loc_fut = FUTEX_INITIALIZER; 127 128 for (size_t i = 0; i < iters; ++i) { 129 futex_down(&loc_fut); 130 /* no-op */ 131 compiler_barrier(); 132 futex_up(&loc_fut); 133 } 134 } 122 135 123 136 static void thread_func(void *arg) … … 125 138 bench_t *bench = (bench_t*)arg; 126 139 127 switch (bench->type) { 128 case T_KERN_FUTEX: 129 kernel_futex_bench(bench); 130 break; 131 case T_LIBC_FUTEX: 132 libc_futex_bench(bench); 133 break; 134 default: 135 assert(false); 136 } 140 bench->func(bench); 137 141 138 142 /* Signal another thread completed. */ … … 175 179 } 176 180 181 static const char *results_txt = "/tmp/rcu-bench-results.txt"; 182 183 static bool open_results(void) 184 { 185 results_fd = fopen(results_txt, "a"); 186 return NULL != results_fd; 187 } 188 189 static void close_results(void) 190 { 191 if (results_fd) { 192 fclose(results_fd); 193 } 194 } 195 196 static void print_res(const char *fmt, ... ) 197 { 198 va_list args; 199 va_start(args, fmt); 200 201 vfprintf(results_fd, fmt, args); 202 vprintf(fmt, args); 203 204 va_end(args); 205 } 206 177 207 static void print_usage(void) 178 208 { 179 209 printf("rcubench [test-name] [k-iterations] [n-threads] {work-size}\n"); 210 printf("Available tests: \n"); 211 printf(" ke-futex .. threads down/up a shared futex and do some work when\n"); 212 printf(" in critical section; do a little less work outside CS.\n"); 213 printf(" lock .. threads lock/unlock separate futexes.\n"); 214 printf(" sema .. threads down/up separate futexes.\n"); 180 215 printf("eg:\n"); 181 printf(" rcubench ke 182 printf(" rcubench l ibc 100000 2\n");183 printf(" rcubench def-ke\n");184 printf(" rcubench def-libc\n");216 printf(" rcubench ke-futex 100000 3 4\n"); 217 printf(" rcubench lock 100000 2 ..runs futex_lock/unlock in a loop\n"); 218 printf(" rcubench sema 100000 2 ..runs futex_down/up in a loop\n"); 219 printf("Results are stored in %s\n", results_txt); 185 220 } 186 221 … … 188 223 const char **err) 189 224 { 190 if (argc < 2) {191 *err = "Benchmark name not specified";192 return false;193 }194 195 futex_initialize(&bench->ke_bench_fut, 1);196 fibril_mutex_initialize(&bench->libc_bench_mtx);197 198 if (0 == str_cmp(argv[1], "def-ke")) {199 bench->type = T_KERN_FUTEX;200 bench->nthreads = 4;201 bench->iters = 1000 * 1000;202 bench->array_size = 10;203 bench->array = malloc(bench->array_size * sizeof(size_t));204 return NULL != bench->array;205 } else if (0 == str_cmp(argv[1], "def-libc")) {206 bench->type = T_LIBC_FUTEX;207 bench->nthreads = 4;208 bench->iters = 1000 * 1000;209 bench->array_size = 0;210 bench->array = NULL;211 return true;212 } else if (0 == str_cmp(argv[1], "ke")) {213 bench->type = T_KERN_FUTEX;214 } else if (0 == str_cmp(argv[1], "libc")) {215 bench->type = T_LIBC_FUTEX;216 } else {217 *err = "Unknown test name";218 return false;219 }220 221 225 if (argc < 4) { 222 226 *err = "Not enough parameters"; 223 227 return false; 224 228 } 225 229 230 futex_initialize(&bench->bench_fut, 1); 231 232 if (0 == str_cmp(argv[1], "ke-futex")) { 233 bench->func = kernel_futex_bench; 234 } else if (0 == str_cmp(argv[1], "lock")) { 235 bench->func = libc_futex_lock_bench; 236 } else if (0 == str_cmp(argv[1], "sema")) { 237 bench->func = libc_futex_sema_bench; 238 } else { 239 *err = "Unknown test name"; 240 return false; 241 } 242 243 bench->name = argv[1]; 244 245 /* Determine iteration count. */ 226 246 uint32_t iter_cnt = 0; 227 247 int ret = str_uint32_t(argv[2], NULL, 0, true, &iter_cnt); … … 234 254 } 235 255 256 /* Determine thread count. */ 236 257 uint32_t thread_cnt = 0; 237 258 ret = str_uint32_t(argv[3], NULL, 0, true, &thread_cnt); … … 244 265 } 245 266 267 /* Set work array size. */ 246 268 if (argc > 4) { 247 269 uint32_t work_size = 0; … … 258 280 } 259 281 282 /* Allocate work array. */ 260 283 if (0 < bench->array_size) { 261 284 bench->array = malloc(bench->array_size * sizeof(size_t)); … … 284 307 } 285 308 286 printf("Running '%s' futex bench in '%zu' threads with '%zu' iterations.\n", 287 bench.type == T_KERN_FUTEX ? "kernel" : "libc", 288 bench.nthreads, bench.iters); 309 open_results(); 310 311 print_res("Running '%s' futex bench in '%zu' threads with '%zu' iterations.\n", 312 bench.name, bench.nthreads, bench.iters); 289 313 290 314 struct timeval start, end; … … 296 320 int64_t duration = tv_sub(&end, &start); 297 321 298 if (0 == duration)299 duration = 1;300 301 322 uint64_t secs = (uint64_t)duration / 1000 / 1000; 302 323 uint64_t total_iters = (uint64_t)bench.iters * bench.nthreads; 303 uint64_t iters_per_sec = total_iters * 1000 * 1000 / duration; 304 305 printf("Completed %" PRIu64 " iterations in %" PRId64 " usecs (%" PRIu64 324 uint64_t iters_per_sec = 0; 325 326 if (0 < duration) { 327 iters_per_sec = total_iters * 1000 * 1000 / duration; 328 } 329 330 print_res("Completed %" PRIu64 " iterations in %" PRId64 " usecs (%" PRIu64 306 331 " secs); %" PRIu64 " iters/sec\n", 307 332 total_iters, duration, secs, iters_per_sec); 333 334 close_results(); 308 335 309 336 return 0;
Note:
See TracChangeset
for help on using the changeset viewer.