source: benchmark/readyQ/rq_bench.hfa

Last change on this file was aec2c022, checked in by Thierry Delisle <tdelisle@…>, 20 months ago

Clean-up the benchmarks a little

  • Property mode set to 100644
File size: 3.4 KB
Line 
1#include <clock.hfa>
2#include <kernel.hfa>
3#include <locale.h>
4#include <parseargs.hfa>
5#include <stdio.h>
6#include <stdlib.hfa>
7#include <stats.hfa>
8#include <thread.hfa>
9#include <time.hfa>
10#include <unistd.h>
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 thread_loop for(this.count = 0;; this.count++)
22
23#define BENCH_OPT \
24        {'d', "duration",  "Duration of the experiments in seconds", duration }, \
25        {'i', "iterations",  "Number of iterations of the experiments", stop_count }, \
26        {'t', "nthreads",  "Number of threads to use", nthreads }, \
27        {'p', "nprocs",    "Number of processors to use", nprocs }
28
29#define BENCH_OPT_PARSE(name) \
30        { \
31                int opt_cnt = sizeof(opt) / sizeof(cfa_option); \
32                char **left; \
33                parse_args( argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, left ); \
34                if(duration > 0 && stop_count > 0) { \
35                        fprintf(stderr, "--duration and --iterations cannot be used together\n"); \
36                        print_args_usage(argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, true); \
37                } else if(duration > 0) { \
38                        clock_mode = true; \
39                        stop_count = 0xFFFFFFFFFFFFFFFF; \
40                        printf("Running for %lf seconds\n", duration); \
41                } else if(stop_count > 0) { \
42                        clock_mode = false; \
43                        printf("Running for %llu iterations\n", stop_count); \
44                } else { \
45                        duration = 5; clock_mode = true;\
46                        printf("Running for %lf seconds\n", duration); \
47                } \
48        }
49
50struct cluster & bench_cluster;
51
52struct BenchCluster {
53        cluster cl;
54        processor * procs;
55        unsigned nprocs;
56};
57
58void ?{}( BenchCluster & this, unsigned nprocs ) {
59        (this.cl){ "Benchmark Cluster" };
60        &bench_cluster = &this.cl;
61        this.nprocs = nprocs;
62        this.procs  = alloc( this.nprocs );
63        for(i; this.nprocs){
64                processor * p = &this.procs[i];
65                (*p){ "Benchmark Processor", this.cl };
66        }
67        #if !defined(__CFA_NO_STATISTICS__)
68                print_stats_at_exit( this.cl, CFA_STATS_READY_Q );
69        #endif
70}
71
72void ^?{}( BenchCluster & this ) {
73        adelete( this.procs );
74        ^(this.cl){};
75}
76
77void wait(const Time & start, bool is_tty) {
78        for() {
79                sleep(100`ms);
80                Time end = timeHiRes();
81                Duration delta = end - start;
82                if(is_tty) {
83                        printf(" %.1f\r", delta`ds);
84                        fflush(stdout);
85                }
86                if( clock_mode && delta >= duration`s ) {
87                        break;
88                }
89                else if( !clock_mode && threads_left == 0 ) {
90                        break;
91                }
92        }
93}
94
95struct __attribute__((aligned(128))) bench_sem {
96        struct thread$ * volatile ptr;
97};
98
99static inline {
100        void  ?{}(bench_sem & this) {
101                this.ptr = 0p;
102        }
103
104        void ^?{}(bench_sem & this) {}
105
106        bool wait(bench_sem & this) {
107                for() {
108                        struct thread$ * expected = this.ptr;
109                        if(expected == 1p) {
110                                if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
111                                        return false;
112                                }
113                        }
114                        else {
115                                /* paranoid */ verify( expected == 0p );
116                                if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
117                                        park();
118                                        return true;
119                                }
120                        }
121
122                }
123        }
124
125        bool post(bench_sem & this) {
126                for() {
127                        struct thread$ * expected = this.ptr;
128                        if(expected == 1p) return false;
129                        if(expected == 0p) {
130                                if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
131                                        return false;
132                                }
133                        }
134                        else {
135                                if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
136                                        unpark( expected );
137                                        return true;
138                                }
139                        }
140                }
141        }
142}
Note: See TracBrowser for help on using the repository browser.