source: benchmark/readyQ/rq_bench.hfa @ b374dbc

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since b374dbc was 1d5deea, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Benchmarks now print stats at exit

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