source: benchmark/readyQ/rq_bench.hfa@ 0497b6ba

Last change on this file since 0497b6ba was aec2c022, checked in by Thierry Delisle <tdelisle@…>, 3 years 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.