Changeset 7554e41 in mainline for uspace/app/rcubench/rcubench.c


Ignore:
Timestamp:
2012-12-04T19:36:10Z (12 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f74ec77
Parents:
af5dfa5b
Message:

rcubench: Added futex upgradable lock vs plain semaphore benchmarks. Dumps results to file.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/rcubench/rcubench.c

    raf5dfa5b r7554e41  
    5050#include <rcu.h>
    5151
     52
     53/* Results are printed to this file in addition to stdout. */
     54static FILE *results_fd = NULL;
     55
    5256typedef struct bench {
    53         enum {
    54                 T_KERN_FUTEX,
    55                 T_LIBC_FUTEX
    56         } type;
     57        const char *name;
     58        void (*func)(struct bench *);
    5759        size_t iters;
    5860        size_t nthreads;
     
    6163        futex_t done_threads;
    6264       
    63         futex_t ke_bench_fut;
    64         fibril_mutex_t libc_bench_mtx;
     65        futex_t bench_fut;
    6566} bench_t;
    6667
     
    8283static void  kernel_futex_bench(bench_t *bench)
    8384{
    84         futex_t * const fut = &bench->ke_bench_fut;
     85        futex_t * const fut = &bench->bench_fut;
    8586        const size_t iters = bench->iters;
    8687        size_t sum = 0;
     
    107108}
    108109
    109 static void libc_futex_bench(bench_t *bench)
    110 {
    111         fibril_mutex_t * const mtx = &bench->libc_bench_mtx;
     110static void libc_futex_lock_bench(bench_t *bench)
     111{
    112112        const size_t iters = bench->iters;
     113        futex_t loc_fut = FUTEX_INITIALIZER;
    113114       
    114115        for (size_t i = 0; i < iters; ++i) {
    115                 fibril_mutex_lock(mtx);
     116                futex_lock(&loc_fut);
    116117                /* no-op */
    117118                compiler_barrier();
    118                 fibril_mutex_unlock(mtx);
    119         }
    120 }
    121 
     119                futex_unlock(&loc_fut);
     120        }
     121}
     122
     123static 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}
    122135
    123136static void thread_func(void *arg)
     
    125138        bench_t *bench = (bench_t*)arg;
    126139       
    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);
    137141       
    138142        /* Signal another thread completed. */
     
    175179}
    176180
     181static const char *results_txt = "/tmp/rcu-bench-results.txt";
     182
     183static bool open_results(void)
     184{
     185        results_fd = fopen(results_txt, "a");
     186        return NULL != results_fd;
     187}
     188
     189static void close_results(void)
     190{
     191        if (results_fd) {
     192                fclose(results_fd);
     193        }
     194}
     195
     196static 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
    177207static void print_usage(void)
    178208{
    179209        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");
    180215        printf("eg:\n");
    181         printf("  rcubench ke   100000 3 4\n");
    182         printf("  rcubench libc 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);
    185220}
    186221
     
    188223        const char **err)
    189224{
    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        
    221225        if (argc < 4) {
    222226                *err = "Not enough parameters";
    223227                return false;
    224228        }
    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. */
    226246        uint32_t iter_cnt = 0;
    227247        int ret = str_uint32_t(argv[2], NULL, 0, true, &iter_cnt);
     
    234254        }
    235255       
     256        /* Determine thread count. */
    236257        uint32_t thread_cnt = 0;
    237258        ret = str_uint32_t(argv[3], NULL, 0, true, &thread_cnt);
     
    244265        }
    245266       
     267        /* Set work array size. */
    246268        if (argc > 4) {
    247269                uint32_t work_size = 0;
     
    258280        }
    259281       
     282        /* Allocate work array. */
    260283        if (0 < bench->array_size) {
    261284                bench->array = malloc(bench->array_size * sizeof(size_t));
     
    284307        }
    285308       
    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);
    289313       
    290314        struct timeval start, end;
     
    296320        int64_t duration = tv_sub(&end, &start);
    297321       
    298         if (0 == duration)
    299                 duration = 1;
    300        
    301322        uint64_t secs = (uint64_t)duration / 1000 / 1000;
    302323        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
    306331                " secs); %" PRIu64 " iters/sec\n",
    307332                total_iters, duration, secs, iters_per_sec);   
     333
     334        close_results();
    308335       
    309336        return 0;
Note: See TracChangeset for help on using the changeset viewer.