source: benchmark/readyQ/cycle.cpp @ e3282fe

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

Some fixes to cycle benchmark and added a pthread version

  • Property mode set to 100644
File size: 3.7 KB
Line 
1
2#include "rq_bench.hpp"
3#include <libfibre/fibre.h>
4
5class __attribute__((aligned(128))) bench_sem {
6        Fibre * volatile ptr = nullptr;
7public:
8        inline bool wait() {
9                static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
10                for(;;) {
11                        Fibre * expected = this->ptr;
12                        if(expected == ready) {
13                                if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
14                                        return false;
15                                }
16                        }
17                        else {
18                                /* paranoid */ assert( expected == nullptr );
19                                if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
20                                        fibre_park();
21                                        return true;
22                                }
23                        }
24
25                }
26        }
27
28        inline bool post() {
29                static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
30                for(;;) {
31                        Fibre * expected = this->ptr;
32                        if(expected == ready) return false;
33                        if(expected == nullptr) {
34                                if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
35                                        return false;
36                                }
37                        }
38                        else {
39                                if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
40                                        fibre_unpark( expected );
41                                        return true;
42                                }
43                        }
44                }
45        }
46};
47struct Partner {
48        unsigned long long count  = 0;
49        unsigned long long blocks = 0;
50        bench_sem self;
51        bench_sem * next;
52};
53
54void partner_main( Partner * self ) {
55        self->count = 0;
56        for(;;) {
57                self->blocks += self->self.wait();
58                self->next->post();
59                self->count ++;
60                if( clock_mode && stop) break;
61                if(!clock_mode && self->count >= stop_count) break;
62        }
63
64        __atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST);
65}
66
67int main(int argc, char * argv[]) {
68        unsigned ring_size = 2;
69        option_t opt[] = {
70                BENCH_OPT,
71                { 'r', "ringsize", "Number of threads in a cycle", ring_size }
72        };
73        BENCH_OPT_PARSE("cforall cycle benchmark");
74
75        {
76                unsigned long long global_counter = 0;
77                unsigned long long global_blocks  = 0;
78                unsigned tthreads = nthreads * ring_size;
79                uint64_t start, end;
80                FibreInit(1, nprocs);
81                {
82                        threads_left = tthreads;
83                        Fibre * threads[tthreads];
84                        Partner thddata[tthreads];
85                        for(int i = 0; i < tthreads; i++) {
86                                unsigned pi = (i + nthreads) % tthreads;
87                                thddata[i].next = &thddata[pi].self;
88                        }
89                        for(int i = 0; i < tthreads; i++) {
90                                threads[i] = new Fibre( reinterpret_cast<void (*)(void *)>(partner_main), &thddata[i] );
91                        }
92                        printf("Starting\n");
93
94                        bool is_tty = isatty(STDOUT_FILENO);
95                        start = getTimeNsec();
96
97                        for(int i = 0; i < nthreads; i++) {
98                                thddata[i].self.post();
99                        }
100                        wait<Fibre>(start, is_tty);
101
102                        stop = true;
103                        end = getTimeNsec();
104                        printf("\nDone\n");
105
106                        for(int i = 0; i < tthreads; i++) {
107                                thddata[i].self.post();
108                                fibre_join( threads[i], nullptr );
109                                global_counter += thddata[i].count;
110                                global_blocks  += thddata[i].blocks;
111                        }
112                }
113
114                printf("Duration (ms)        : %'ld\n", to_miliseconds(end - start));
115                printf("Number of processors : %'d\n", nprocs);
116                printf("Number of threads    : %'d\n", tthreads);
117                printf("Cycle size (# thrds) : %'d\n", ring_size);
118                printf("Total Operations(ops): %'15llu\n", global_counter);
119                printf("Total blocks         : %'15llu\n", global_blocks);
120                printf("Ops per second       : %'18.2lf\n", ((double)global_counter) / to_fseconds(end - start));
121                printf("ns per ops           : %'18.2lf\n", ((double)(end - start)) / global_counter);
122                printf("Ops per threads      : %'15llu\n", global_counter / tthreads);
123                printf("Ops per procs        : %'15llu\n", global_counter / nprocs);
124                printf("Ops/sec/procs        : %'18.2lf\n", (((double)global_counter) / nprocs) / to_fseconds(end - start));
125                printf("ns per ops/procs     : %'18.2lf\n", ((double)(end - start)) / (global_counter / nprocs));
126                fflush(stdout);
127        }
128
129        return 0;
130}
Note: See TracBrowser for help on using the repository browser.